Ruby on rails 4 Rails 4-同时有一个和多个
我有以下设置:Ruby on rails 4 Rails 4-同时有一个和多个,ruby-on-rails-4,associations,Ruby On Rails 4,Associations,我有以下设置: class Album < ActiveRecord::Base has_many :photos end class Photo < ActiveRecord::Base belongs_to :album end 另一种方法是向Photo模型添加布尔值,如photos.is_profile\u Photo,然后在类中创建一个范围关联,但我觉得这不是最佳的,因为: 我必须保持相册照片的同步,因此只有一张的布尔值设置为1 将信息添加到照片表中,以便将其与
class Album < ActiveRecord::Base
has_many :photos
end
class Photo < ActiveRecord::Base
belongs_to :album
end
另一种方法是向Photo
模型添加布尔值,如photos.is_profile\u Photo
,然后在类中创建一个范围关联,但我觉得这不是最佳的,因为:
- 我必须保持相册照片的同步,因此只有一张的布尔值设置为1
- 将信息添加到照片表中,以便将其与相册表相关联。如果我想要相册外的照片,它们将有两个额外字段
和is\u profile\u photo
,这是没有意义的is\u cover\u photo
是否有一种“Rails方式”可以做到这一点,而我却缺少这种方式?我会在相册表中添加两列
profile_photo_id
cover_photo_id
他们会持有照片的id,即个人资料和/或封面照片
然后,在相册模型中,您可以轻松添加:
belongs_to :profile_photo, class_name: "Photo"
belongs_to :cover_photo, class_name: "Photo"
然后在照片模型中,您需要:
has_many :profile_albums, class_name: "Album", foreign_key: "profile_photo_id"
has_many :cover_albums, class_name: "Album", foreign_key: "cover_photo_id"
(请注意,您可以随意命名它们,我选择了它们。您只需要class_name和foreign_键来指向具有该id列的正确模型)
那么您有以下关联:
Album.profile_photo=>返回相册中ID为的照片
Photo.profile_albums=>将包含照片的所有相册作为配置文件图片返回
(封面照片也是如此)我终于采用了我提到的第二种方法
class AddCoverAndProfileToPhotos < ActiveRecord::Migration
def change
add_column :photos, :is_profile, :boolean, default: false
add_column :photos, :is_cover, :boolean, default: false
end
end
class AddCoverage和ProfileTophotos
专辑类别:
class Album < ActiveRecord::Base
has_many :photos, inverse_of: :album, dependent: :destroy
has_one :profile_photo,
-> { where is_profile: true },
class_name: 'Photo'
has_one :cover_photo,
-> { where is_cover: true },
class_name: 'Photo'
accepts_nested_attributes_for :photos, allow_destroy: true
delegate :empty?, to: :photos
validates_associated :photos
def remove_profile_photo
profile_photo.update(is_profile: false) if profile_photo.present?
end
def remove_cover_photo
cover_photo.update(is_cover: false) if cover_photo.present?
end
def set_profile_photo(photo)
remove_profile_photo
photo.update(is_profile: true)
end
def set_cover_photo(photo)
remove_cover_photo
photo.update(is_cover: true)
end
end
classalbum{哪里是_profile:true},
类名:“照片”
有一张:封面照片,
->{u cover:true}在哪里,
类名:“照片”
接受\u嵌套的\u属性\u用于:照片,允许\u销毁:true
委托:空?,收件人::照片
验证关联的照片
def删除_配置文件_照片
如果profile\u photo.present存在,是否更新(profile:false)?
结束
def取下盖子照片
封面照片。如果封面照片存在,是否更新(封面:假)?
结束
def设置配置文件照片(照片)
删除\u个人资料\u照片
照片。更新(个人资料:真)
结束
def套件盖照片(照片)
取下照片的封面
照片。更新(封面:真实)
结束
结束
最后是摄影课:
class Photo < ActiveRecord::Base
mount_uploader :image, PhotoUploader
belongs_to :album
validates_presence_of :image
validates_presence_of :album
validates_uniqueness_of :is_profile, scope: :album, if: :is_profile?
validates_uniqueness_of :is_cover, scope: :album, if: :is_cover?
end
class-Photo
我不确定我是否完全理解您的用例,但您看过STI吗?如果你不熟悉,这是一个很好的概述。我不认为这是一个复杂的用例,只是尝试一个相册模型,其中有一组照片需要标记为特殊的(个人资料和封面),Facebook风格。虽然不确定STI如何适合这里,但是对于ProfilePhoto
/CoverPhoto
(如果你是这么建议的话)使用不同的类感觉太过分了。正如问题中所述,这是我尝试的第一件事。问题是,has\u one
希望在关系的另一端有一个属于
,并且在执行@album.profile\u photo
时生成的SQL查询检查照片。album\u id
而不是您提到的两列。我修复了它。因此,这种联系是倒退的,你在相册中有一个属于,在照片中有许多属于。我已经用一个快速rails应用程序对它进行了测试,但是如果它不起作用,请告诉我。
class Photo < ActiveRecord::Base
mount_uploader :image, PhotoUploader
belongs_to :album
validates_presence_of :image
validates_presence_of :album
validates_uniqueness_of :is_profile, scope: :album, if: :is_profile?
validates_uniqueness_of :is_cover, scope: :album, if: :is_cover?
end