简体   繁体   English

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

[英]Multiple polymorphic association on a same model in rails

I have a polymorphic association on an Image model and need to have two associations on it from a Place model. 我在Image模型上有一个多态关联,并且需要从Place模型上有两个关联。 Something like: 就像是:

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

This obviously doesn't work has the Image model doesn't know the difference between pictures and cover_image and every image is stored with 这显然是行不通的,因为Image模型不知道picture和cover_image之间的区别,并且每个图像都存储在

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

I was thinking about adding a imageable_sub_type column to Image to store a subtype.. So my images would look like: 我正在考虑向Image添加imageable_sub_type列以存储子类型。因此,我的图像如下所示:

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

I can easily retrieve only the images with that subtype from my association in Place : 我可以很容易地从我在Place关联中检索具有该子类型的图像:

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

But I don't find a way to set this value while adding an image to a Place (actually it is always set to nil ). 但是我找不到在将图像添加到Place时设置此值的方法(实际上始终将其设置为nil )。

Is there a way to do that? 有没有办法做到这一点?


I tried to do it this way: https://stackoverflow.com/a/3078286/1015177 but the problem remains the same, the imageable_sub_type remains nil . 我尝试这样做: https : //stackoverflow.com/a/3078286/1015177但问题仍然相同, imageable_sub_type仍然为nil

When using a condition on a relation, it will assign that condition if you build the record through the relation (ie using create_cover_image). 在关系上使用条件时,如果您通过关系构建记录(即使用create_cover_image),它将分配该条件。

If you want it to change the value of imageable_sub_type when assigning an exiting instance of Image, then you could overwrite cover_image= to do that. 如果您希望它在分配现有的Image实例时更改imageable_sub_type的值,则可以覆盖cover_image =来做到这一点。 ie

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

by adding the condition in the relation, it is letting you retrieve the images with imageable_sub_type = cover_image when you call place.cover_image . 通过在关系中添加条件,可以在调用place.cover_image时检索imageable_sub_type = cover_imageimages It will not set the attribute for you when you add the image. 添加图像时,它不会为您设置属性。 That has to be done separately when the image is added based on some input from the view like a checkbox tag. 当基于视图的某些输入(例如复选框标签)添加图像时,必须单独完成此操作。

Update: You can override the default association= method , sthing like below in Place model: 更新:您可以覆盖默认的association= method,如下所示在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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM