1

我一直在寻找 AR 中的这种功能,但似乎找不到。AR 的 Dirty 实现表明,一个已经持久化的实例只有在其直接属性之一发生变化时才被认为是脏的。所以,让我们说:

class Picture < ActiveRecord::Base
  belongs_to :gallery
  has_one :frame
end

在这种情况下,我可以执行以下操作:

p = Picture.new(:gallery => Gallery.new, :frame => Frame.new)
p.save #=> it will save the three instances
p.gallery = Gallery.new
p.save #=> will not save the new gallery
p.gallery_id_will_change!
p.gallery = Gallery.new
p.save #=> this will save the new Gallery

但现在我不能为 has_one 关联做类似的事情,因为 Picture 实现不拥有引用它的属性。因此,似乎这种肮脏的标记是不可能的。或者不是吗?

4

2 回答 2

1

我能想到的最好的事情是:

class Picture < ActiveRecord::Base
  belongs_to :gallery
  has_one :frame

  after_save :force_save_frame

  def force_save_frame
    frame.save! if frame.changed?
  end
end
于 2013-02-15T23:41:14.287 回答
1

就像weexpectedTHIS所说,脏标志是为模型本身的属性设置的,而不是为相关对象设置的。它仅适用于 belongs_to 因为模型上有一个外键。

但你可以做这样的把戏

module FrameDirtyStateTracking
  def frame=(frame)
    attribute_will_change!('frame')
    super
  end
end

class Picture < ActiveRecord::Base
  prepend FrameDirtyStateTracking

  belongs_to :gallery
  has_one :frame
end

picture = Picture.new
picture.frame = Frame.new
picture.changed? # => true
picture.changed # => ['frame']
于 2015-09-18T09:29:54.213 回答