Reputation: 10852
Here's my schema:
Participant =
id: int
user_id: int
program_id: int
... other fields
end
User =
id: int
name: text
... other fields
end
Program =
id: int
user_id: int # this is the manager of the program
end
So, in English:
And so in Rails:
class Participant
belongs_to :user
belongs_to
end
class User
has_many :programs
has_many :participants
end
class Program
has_many :participants
belongs_to :user
end
Notice that a user really has_many programs, the ones that they manage, as well as has_many programs through participants, which is all the programs that they participate in.
What I want is to be able to say:
So two flavors of user has_many programs. I need to do some magic combination of :through, :as, :class, or something along those lines but I can't figure it out so far.
One additional question continuing this example. I now have
class User
has_many :participations, class_name: "Participant"
has_many :moderated_programs, class_name: "Program", foreign_key: 'moderator_id'
has_many :participating_programs, through: :participations, class_name: "Program", source: :program
end
class Participant
belongs_to :user
belongs_to :program
end
Notice the third line. What I want is to take advantage of this series of associations: a participant has a user_id and a program_id. I would like to be able to say u1.participating_programs and get a list of one or more programs this user participates in, but the above is not working. Can you tell where I am off base?
Upvotes: 1
Views: 114
Reputation: 18070
I agree with Charles, you have some wording/language issues that are confusing things. Participations may be a better term. I wouldn't recommend polymorphic here - the user may have two different roles, but the users won't be of a different type. Especially if it's possible for a manager to also be a participant...
class User
has_many :participations
has_many :programs, through: :participations
has_many :managed_programs, class_name: 'Program'
end
class Program
belongs_to :manager, class_name: 'User'
has_many :participations
has_many :users, through: :participations
end
# Just a join table. Nothing special
class Participation
belongs_to :user
belongs_to :program
end
Upvotes: 2
Reputation: 14275
First off, just a language thing: I don't think a user has many participants. He is a participant or he is the manager of a program. So he rather has many participations.
You can write this as follows:
class User
has_many :participations, class_name: "Participant"
has_many :managed_programs, class_name: "Program"
end
Also, at least in your code above, the Participant class is missing
belongs_to :user
Since it appears that you need to differentiate between two different types of users, the polymorphic
functionality would come in handy. Then you don't need an extra participant table. See here.
Upvotes: 1