关于在rails中使用多态关联的问题

时间:2010-12-15 17:12:21

标签: ruby-on-rails

伙计们 我是rails的新手,这是我的代码:

class Video < ActiveRecord::Base
  belongs_to :videoable, :polymorphic => true
end

class Drummer < ActiveRecord::Base
  has_many :videos,:as => :videoable
end


class Cymbal < ActiveRecord::Base
  has_many :videos, :as => :videoable
end

从这一点开始,我可以使用drummer.videos获取属于鼓手的所有视频, 但我不能使用video.drummer来获取视频所属的人。

当然我可以使用video.where(:videoable_id =&gt;'1',:videoable_type =&gt;'鼓手')来找到确切的鼓手记录,但我觉得必须有优雅的做法在rails中,对吧?

还有一个问题,我想要改善这种关联,视频和鼓手,视频和钹应该是多对多的,有时在一个视频中有超过1个鼓手或1个钹,所以这样做是有意义的这条路。我怎样才能做到这一点?

3 个答案:

答案 0 :(得分:1)

如果它始终是您想要的一对多关系(视频最多可以有一个鼓手),您可以将这些行添加到您的视频模型中:

belongs_to :drummer, :class_name => "Drummer", :foreign_key => "videoable_id"
belongs_to :cymbal, :class_name => "Cymbal", :foreign_key => "videoable_id"

Rails将确定外键映射到哪个类并获取正确的条目。

答案 1 :(得分:1)

答案 2 :(得分:1)

如果您的DrummerCymbal模型相似,则可以考虑使用STI而不是多态。定义一个位于type列的新模型作为父项,并添加has_many关联,然后添加子模型:

class Subject < ActiveRecord::Base
  has_many :subject_videos, :dependent => :destroy
  has_many :videos, :through => :subject_videos
end

class Drummer < Subject
end

class Cymbal < Subject
end

使用外键subject_idvideo_id添加SubjectVideo模型。然后通过它关联您的视频模型:

class Video < ActiveRecord::Base
  has_many :subject_videos, :dependent => :destroy
  has_many :subjects, :through => :subject_videos
end

现在你有一个多对多的关联。

d = Drummer.create
d.videos # []
d.videos.create(:name=>"Stompin' at the Savoy")
v = Video.find_by_name("Stompin' at the Savoy")
v.subjects # [Drummer]

这种方法的主要缺点是Drummer和Cymbal现在存储在同一个表中,如果它们共享很少的列,这可能是不可取的。

如果仍需要使用多态的多对多关系,请查看has_many_polymorphs