我有两个类Product
和user
,它们与多态类型有has_many
关系。
class User < ActiveRecord::Base
has_many :pictures, as: :imageable
end
class Product < ActiveRecord::Base
has_many :pictures, as: :imageable
end
class Picture < ActiveRecord::Base
belongs_to :imageable, polymorphic: true
end
我还要为profile_picture
的用户模型添加新属性,以便@user.profile_picture
将返回图片对象。怎么能实现呢?特别是要向用户添加外键的迁移。
编辑:我已经更新了用户模型
has_one :profile_picture, class_name: "Picture", foreign_key: "profile_picture_id"
并添加了以下迁移
add_column :users, :profile_picture_id, :integer
然而,如果有人能够解释我到底做错了什么,我似乎无法设置个人资料图片,我将不胜感激。谢谢!
答案 0 :(得分:1)
class User < ActiveRecord::Base
has_many :pictures
has_one :profile_picture, :class_name => "Picture"
end
class Product < ActiveRecord::Base
has_many :pictures
end
class Picture < ActiveRecord::Base
belongs_to :imageable, polymorphic: true
end
答案 1 :(得分:0)
正确使用关联时,没有直接方法来实现此目的。
数据结构错误。您正尝试以两种不同的方式关联同一个模型。问题是:这两种方式相互干扰。
您正在尝试使用相同类型存储不同类型的对象。直接的方式(在另一个答案中建议)将使您无法确定哪些只是User
的图片以及他们中的profile_picture
是什么。因此,任何可能的解决方案都需要添加区分profile_picture
的方法。
就在昨天我写了an example on how to use "single table inheritance"。它实际上非常适合这里,您需要两个类似的数据结构以不同的方式运行。为了使它工作,你需要两件事:
向pictures
表添加STI支持:
rails g migration AddTypeToPictures type:string:index
...并确保添加type
类型为string
的列,并在其上添加索引。
rails g model ProfilePicture --no-migration --parent=Picture
此类将被创建为空,但将继承Picture
的所有内容,因此在许多情况下它应保持为空。
然后只需一个简单的关联就可以在任何类上使用:
has_one :profile_picture, as: :imageable
我们假设我们将其添加到User
。然后,查找User
的个人资料图片的搜索条件为:
type
是"ProfilePicture"
imageable_type
是"User"
imageable_id
等于相关用户的id
搜索变得很麻烦,对吧?嗯,这应该有效,但我不建议所有这些,它有影响和替代方案:
ProfilePicture
的数据库列,都必须将其添加到Picture
,即使它未被使用:它们也存储在同一个表中。 ProfilePicture
成为一个成熟的模型:为其创建一个表,使其继承ActiveRecord::Base
。Picture
相同:这将不需要额外的查询来获取个人资料图片。