1

I have a complex active record relationship in mind, and was wondering how exactly I would accomplish it. In essence:

A User can create a Board. A user can then add other users to that board for collaborative editing. Added users form a Team. Each added User has a Role in each board, (Admin, Editor, Viewer).

I was thinking of setting it up this way:

  • A User has many Boards

  • A Board has many Users through Teams

  • A Team has many Users?

The role part has been confusing me. Do I have to set up a TeamUser model which has many Roles, or does each User have many Roles which belong to a Board? Does a Role even have to be it's own model?

What is the most effective way to accomplish my goal?

I_A
  • 331
  • 2
  • 14

1 Answers1

1

If a user could belong to many teams and could have many roles, logic could be something like:

You need a join table to supply the N-to-N relationship between User and Board model. But the thing is, when you add a user to a board, you give them a role in that participation. It's a good place to hold role info in that participation. So our UsersBoards join-table transform into the Participation model (Or whatever you like to call it). Our participation model now holds the user, board and role info (All of them is foreign-key).

I didn't exactly understand the purpose of the Team model but I think it's easy to add a user to a team when it's necessary. It will not hurt to our logic.

Also, if you don't plan to add more features in the future, role can be an enum too.

class User < ApplicationRecord
  has_many :participations
  has_many :boards, through: :participations
end

class Board < ApplicationRecord
  has_many :participations
  has_many :users, through: :participations
end

class Participation < ApplicationRecord
  belongs_to :user
  belongs_to :board
  enum role: [ :admin, :editor, :viewer ]
end

user = User.first
user.participations.first.board #Board
user.participations.first.admin? #true
user.boards

And you can add helper methods or delegate to models for shortening the query.

Yunus Emre
  • 390
  • 3
  • 9
  • I was thinking of using the Team model as the join-table between users and boards. A team has many users, and a board would have one team. – I_A Apr 05 '20 at 00:02
  • It would be helpful if you could list the belongs_to and has_many relationships that I would have to setup to achieve this. From what I understand, the User model would be: `has_many :boards, through: :participation`. The Boards model would be: `has_many :users, through: :participation`. ­ The Participation model would be: `belongs_to: user; belongs_to: board; has_one: role`. And the Role model would be: `belongs_to: participation`? – I_A Apr 05 '20 at 00:09
  • I just edited my answer and added a code example too. Happy hacking! – Yunus Emre Apr 05 '20 at 00:21