gpt4 book ai didi

ruby-on-rails - Rails has_one vs belongs_to 语义

转载 作者:行者123 更新时间:2023-12-03 13:29:12 26 4
gpt4 key购买 nike

我有一个模型代表 Content包含一些图像的项目。图像的数量是固定的,因为这些图像引用非常特定于内容。例如,Content型号引用Image模型两次(个人资料图像和背景图像)。我试图避免泛型 has_many ,并坚持多个 has_one的。当前的数据库结构如下所示:

contents
- id:integer
- integer:profile_image_id
- integer:background_image_id

images
- integer:id
- string:filename
- integer:content_id

我只是不知道如何在这里正确设置关联。 Content模型可以包含两个 belongs_toImage 的引用,但这在语义上似乎并不正确,因为理想情况下图像属于内容,或者换句话说,内容有两个图像。

这是我能想到的最好的(通过打破语义):
class Content
belongs_to :profile_image, :class_name => 'Image', :foreign_key => 'profile_image_id'
belongs_to :background_image, :class_name => 'Image', :foreign_key => 'background_image_id'
end

我离得远吗,还有更好的方法来实现这种关联吗?

最佳答案

简单的答案是将您的关联设置为与您所拥有的相反,如下所示:

# app/models/content.rb
class Content < ActiveRecord::Base
has_one :profile_image, :class_name => 'Image'
has_one :background_image, :class_name => 'Image'
end

# app/models/image.rb
class Image < ActiveRecord::Base
belongs_to :content
end

您根本不需要内容表中的外键“background_image_id”和“profile_image_id”。

然而,有一个更优雅的解决方案:单表继承。现在设置它,以防您希望背景图像和个人资料图像在 future 表现得稍微不同,而且它会在今天澄清您的代码。

首先,在图像表中添加一个名为 type 的列:
# command line
script/generate migration AddTypeToImages type:string
rake db:migrate

现在像这样设置你的模型:
# app/models/content.rb
class Content < ActiveRecord::Base
has_one :profile_image
has_one :background_image
end

# app/models/image.rb
class Image < ActiveRecord::Base
belongs_to :content
end

# app/models/background_image.rb
class BackgroundImage < Image
# background image specific code here
end

# app/models/profile_image.rb
class ProfileImage < Image
# profile image specific code here
end

现在你可以做各种各样的事情,比如获取所有背景图像的列表:
# script/console
BackgroundImage.all

这更适用于您尝试创建的数据模型,允许 future 最简单的可扩展性,并为您今天提供一些很酷的新方法。

更新:

从那以后,我创建了一篇名为 Single-Table Inheritance with Tests 的博客文章。这更详细,并涵盖了测试。

关于ruby-on-rails - Rails has_one vs belongs_to 语义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2136091/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com