在rails中的同一模型上的多个多态关联

时间:2013-09-20 14:26:49

标签: ruby-on-rails activerecord polymorphism

我在Image模型上有多态关联,需要在Place模型上有两个关联。类似的东西:

class Place < ActiveRecord::Base
  has_many :pictures, as: :imageable, class_name: 'Image'
  has_one :cover_image, as: :imageable, class_name: 'Image'
end

class Image < ActiveRecord::Base
  belongs_to :imageable, polymorphic: true
end

如果Image模型不知道图片和cover_image之间的区别并且每个图像都存储在

,这显然不起作用
#<Image ... imageable_id: 17, imageable_type: "Place">

我正在考虑向imageable_sub_type添加Image列来存储子类型。所以我的图片看起来像:

#<Image ... imageable_id: 17, imageable_type: "Place", imageable_sub_type: "cover_image">

我可以轻松地从Place中的关联中检索具有该子类型的图像:

has_one :cover_image, -> { where(imageable_sub_type: 'cover_image'), as: :imageable, class_name: 'Image'

但在向Place添加图片时,我找不到设置此值的方法(实际上它始终设置为nil)。

有办法吗?


我尝试这样做:https://stackoverflow.com/a/3078286/1015177但问题仍然相同,imageable_sub_type仍为nil

2 个答案:

答案 0 :(得分:1)

在关系上使用条件时,如果通过关系构建记录(即使用create_cover_image),它将分配该条件。

如果您希望在分配图像的现有实例时更改imageable_sub_type的值,则可以覆盖cover_image =来执行此操作。即

def cover_image= cover_image
  cover_image.imageable_sub_type = 'cover_image'
  super
end

答案 1 :(得分:0)

通过在关系中添加条件,您可以在调用images时使用imageable_sub_type = cover_image检索place.cover_image。添加图像时,它不会为您设置属性。必须在根据视图中的某些输入(如复选框标记)添加图像时单独完成。

更新:您可以覆盖association=模型中的默认Place方法,如下所示:

 def cover_image=(img)
     # add the img to tthe associated pictures 
     self.pictures << img 

     # mark current img type as cover
     img.update_attribute(:imageable_sub_type, "cover_image")

     # mark all other images type as nil, this to avoid multiple cover images, 
     Picture.update_all( {:imageable_sub_type => nil}, {:id => (self.pictures-[img])} ) 

 end