Arjan
Arjan

Reputation: 6274

Setup a relation from one model to another, using multiple associations

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

Answers (2)

Jordan Running
Jordan Running

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

tadman
tadman

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

Related Questions