修改before_save回调中的子记录

时间:2017-01-31 23:39:52

标签: ruby-on-rails ruby callback

在其父母的before_save回调中修改子记录时苦苦挣扎。

子记录为Photo,其中包含一个名为main的属性,它是一个布尔值。

父记录为Deal

has_many :photos

嵌套修改记录的表单以对deal进行更改,用户还可以更改photo的属性或添加或删除photos

这就是问题所在。我需要总是有一张main照片,我计划在before_save回调中执行此操作,在那里我检查照片,如果main列表中没有照片,我将主要设置为如果列表中的第一张照片为true。

它没有保存儿童记录,我希望如此。我已经添加了调试语句,因此我可以证明该方法正在被调用,我还可以声明main的值被标记为true ...它只是没有被保存。我误解了这个回调吗?光棚会很棒。谢谢你们!

class Deal < ActiveRecord::Base

  has_many :photos, dependent: :destroy
  accepts_nested_attributes_for :photos, allow_destroy: :true

  before_save :set_main_photo


  ### bunch of other unrelated stuff

  private
  def set_main_photo
    if self.photos
      if self.photos.main.nil?
        self.photos.first.main = true
      end
    end
  end   
end 

1 个答案:

答案 0 :(得分:2)

这里有几件事情,但你的主要问题是以这种方式修改孩子不会自动保存记录。您需要更新set_main_photo以便在子记录上调用.save。当你在这里时,其他一些变化是谨慎的:

def set_main_photo
  if photos.any?
    unless photos.main.present?
      photos.first.update_attribute :main, true
    end
  end
end

完成此操作后,您现在以一种尴尬的方式将DealPhotos结合起来,Photo上的属性表示与Deal的关系条件,和Deal管理该属性。更好的方法是创建一个新的关系来对此进行建模,将属性的责任完全在Deal内:

class Deal
  has_many :photos
  belongs_to :main_photo, class_name: 'Photo'
end

class Photo
  belongs_to :deal
end

这样,您只需设置deal.main_photo = deal.photos.first,然后设置deal.save