2

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?

4

1 回答 1

0

尝试这个:

class Play
  has_many :actors_costumes, :through => :actors, :source => :costumes
end

您可以通过以下方式获得演员服装:

play.actors_costumes
于 2013-03-08T05:28:40.600 回答