I am trying to set up the model structure that has a User model Project model along with two join tables setup as has_many through to manage two specific aspects of the Project, ProjectManagers and ProjectMembers.
I can setup two has_and_belongs_to_many but it doesn't feel very railsy.
Right now, this is what I have and I'm unsure of how to proceed to use multiple has_many through (Project Manager, Project Member) both referencing User model.
Would a nested through be the way to go even if a Project Manager will not always be part of the Project User table?
project.rb
class Project < ApplicationRecord
has_many :project_members
has_many :users, through: :project_manager
end
user.rb
class User < ApplicationRecord
has_many :project_managers
has_many :users, through: :project_managers
end
project_manager.rb
class ProjectManager < ApplicationRecord
belongs_to :project
belongs_to :user
end
project_member.rb
class ProjectMember < ApplicationRecord
belongs_to :project
belongs_to :user
end
I don't see any problems with what you're doing. There are other options, but this approach should work as you want. Have you tried it? I'd do something like this.
class Project < ApplicationRecord
has_many :project_members
has_many :project_managers
has_many :members, through: :project_members, :class_name => User.to_s
has_many :managers, through: :project_manager, :class_name => User.to_s
end
Another approach, since the join tables are similar is to subclass them and add a type column to the join table. Not necessarily better than what you're doing.
You could also create a project_users table (don't separate members and managers) and include a "role" column. A scope on project_user.rb would bring back managers or members.
Personally, I would go with your approach. Managers will likely have different auth and have relationships with other objects. It's simpler to query and less likely to make a mistake.
And, I wouldn't recommend a has_and_belongs_to_many
, you're likely to add other columns to the join table and you'll be glad you have the model.