Anu*_*rag 18 model ruby-on-rails associations
我有一个模型表示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
Run Code Online (Sandbox Code Playgroud)
我在这里无法弄清楚如何正确设置关联.该Content模型可以包含两个belongs_to对a的引用Image,但这似乎在语义上不正确,因为理想情况下图像属于内容,或者换句话说,内容具有两个图像.
这是我能想到的最好的(通过打破语义):
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
Run Code Online (Sandbox Code Playgroud)
我离开了,有更好的方法来实现这种关联吗?
Jai*_*yer 23
简单的答案是将您的关联设置为与您拥有的关联相反,如下所示:
# 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
Run Code Online (Sandbox Code Playgroud)
您根本不需要内容表中的外键'background_image_id'和'profile_image_id'.
但是,有一个更优雅的解决方案:单表继承.现在进行设置,以防您希望将来背景和个人资料图片的行为有所不同,此外它将在今天澄清您的代码.
首先,在images表中添加一个名为type的列:
# command line
script/generate migration AddTypeToImages type:string
rake db:migrate
Run Code Online (Sandbox Code Playgroud)
现在设置你的模型如下:
# 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
Run Code Online (Sandbox Code Playgroud)
现在,您可以执行各种操作,例如获取所有背景图像的列表:
# script/console
BackgroundImage.all
Run Code Online (Sandbox Code Playgroud)
对于您尝试创建的数据模型更为正确,允许将来最简单的可扩展性,并为您提供一些很酷的新方法.
更新:
我之后创建了一篇名为Single-Table Inheritance with Tests的博客文章,该文章详细介绍了测试.
| 归档时间: |
|
| 查看次数: |
12304 次 |
| 最近记录: |