Reputation: 6274
I'd like to know how to setup a relation from one model to another, but through multiple associations.
In this example there is a Member
model, a Sportsorginazation
model, a Basketballclub
model and a Footballclub
model (for the sake of this example it is necessary to have these clubs defined as different models).
Let's say this Sportsorganization has multiple Basketballclubs and multiple Footballclubs. The Basketballclubs and Footballclubs both have many members.
How would I get all the members from the sportsorganization?
I can imagine to have something like:
class Sportsorganization
has_many :basketballclubs
has_many :footballclubs
has_many :members, :through => :basketballclubs
end
But how would I get all the members from both the basketballclubs and the footballclubs? I know that you can make an alias for members and let Sportsorganization have basketballclubmembers and footballclubmembers, but is it also possible to get all members using basketballclubs and footballclubs?
Upvotes: 1
Views: 94
Reputation: 106097
@tadman is correct as far as I'm concerned, but there is a naive way to do this:
has_many :basketballclub_members, :through => :basketballclubs, :class_name => 'Member'
has_many :footballclub_members, :through => :footballclubs, :class_name => 'Member'
def all_members
basketballclub_members + footballclub_members
end
This is very naive, though—you'd probably want to memoize (cache) the result of that +
, for example.
Slightly less naive would be to use composed_of
, e.g.:
has_many :basketballclub_members, :through => :basketballclubs, :class_name => 'Member'
has_many :footballclub_members, :through => :footballclubs, :class_name => 'Member'
composed_of :members, [ 'basketballclub_members', 'footballclub_members' ],
:class_name => 'Array',
:constructor => proc {|bb_members, fb_members| bb_members + fb_members }
I haven't tested this so it may need some tweaking, but that's the basic idea.
Caveat emptor, though—with either of these methods you'll lose all of the handy ActiveRecord collection methods (you'll just get a plain old array of objects).
Upvotes: 1
Reputation: 211740
Relationships like this can get more complicated than ActiveRecord's standard patterns can accommodate, so you either need to come up with a creative solution, or you can try and wrangle it back in the box.
One approach that might work is creating an STI model to encapsulate all the different kinds of clubs. A second approach is to associate each of the members back to the associated Sportsorganization directly by de-normalizing an attribute.
Upvotes: 0