Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 4 Rails 4-同时有一个和多个_Ruby On Rails 4_Associations - Fatal编程技术网

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