I have a Play that has many CostumedActors. A CostumedActor is a join of Actors and Costumes which have a many to many relationship.
This seems to be a pattern that should be quite common, but I'm not clear about the best way to do it in rails.
I have currently set it up as a 3-way join association as follows:
class Play < ActiveRecord::Base
has_many :costumed_actors
has_many :actors, :through => costumed_actors
has_many :costumes,:through => costumed_actors
end
class CostumedActor < ActiveRecord::Base
belongs_to :play
belongs_to :costume
belongs_to :actor
end
class Costume < ActiveRecord::Base
has_many :actors, :through => costumed_actors
has_many :plays, :through => costumed_actors
end
class Actor < ActiveRecord::Base
has_many :costumes, :through => costumed_actors
has_many :plays, :through => costumed_actors
end
Rails doesn't handle this perfectly. If I want to see the actors or costumes in a play, no problem:
play.costumes
play.actors
But if I want to see which costume an actor wears, I can't do
play.actors.costumes
In this case the .costumes gives me all the costumes each actor wears, across all plays, not just the current one.
I have to do something like:
play.costumed_actors.where(:actor => @actor).map {|x| x.costumes}
or more cleanly, by adding a helper method to the has_many :through association
class Play
has_many :costumes, :through => costumed_actors do
def for_actor(actor)
where("costumed_actors.actor_id = ?", actor) if !actor.nil?
end
end
end
play.costumes.for_actor(@actor)
Also, adding associations doesn't work correctly. I'd like to be able to do something like
Play.actors << actor.with_costume(costume)
But I can't see how to phase an association helper method, or even if that approach is possible.
Is this the best way to represent this scenario, and if so is this the best way to read/write the associated records?