【问题标题】:has_many :through, 3 way joinhas_many :through, 3 way join
【发布时间】:2013-03-08 04:14:23
【问题描述】:

我有一个有很多 CostumedActors 的剧本。 CostumedActor 是具有多对多关系的 Actor 和 Costumes 的连接。

这似乎是一种应该很常见的模式,但我不清楚在 Rails 中最好的方法。

我目前已将其设置为 3-way join 关联,如下所示:

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 不能完美地处理这个问题。如果我想看剧中的演员或服装,没问题:

play.costumes
play.actors  

但如果我想看看演员穿什么服装,我做不到

play.actors.costumes

在这种情况下,.costumes 为我提供了每个演员在所有戏剧中穿的所有服装,而不仅仅是当前的。

我必须这样做:

play.costumed_actors.where(:actor => @actor).map {|x| x.costumes}

或者更简洁,通过向 has_many :through 关联添加一个辅助方法

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)

此外,添加关联也无法正常工作。我希望能够做类似的事情

Play.actors << actor.with_costume(costume)

但我看不出如何分阶段关联辅助方法,或者即使该方法可行。

这是表示这种情况的最佳方式吗?如果是,这是读取/写入关联记录的最佳方式吗?

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3.1 has-many-through


    【解决方案1】:

    试试这个:

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

    演员服装获取方式如下:

    play.actors_costumes
    

    【讨论】:

    • 谢谢,但这似乎与简单的play.actors 生成完全相同的 SQL 有 3 个关系,对于这种查询,我需要以某种方式指定其中的 2 个,然后得到第三个,如我的示例play.actors.with_costume(costume)。我更大的问题实际上是关于在 rails 中使用 3 表连接(也许更准确地描述为带有查找表的多对多)表示的正确方法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-06
    • 1970-01-01
    • 1970-01-01
    • 2012-11-27
    • 2019-03-04
    • 1970-01-01
    相关资源
    最近更新 更多