通过接受嵌套属性创建后更新回调 运行 - Rails
Update callback running after create via Accepts Nested Attributes - Rails
当我创建一个 Blog
对象时,create
和 update
回调都会按顺序触发。
在这种情况下,更新 Blog
对象会删除所有现有的 images
并生成新的对象。我只想在 create
上生成新的 images
,并在 update
上删除并重新创建它们。
我认为这是由于 accepts_nested_attributes_for
中的嵌套对象造成的,但我似乎找不到可行的替代方法。
这是 Rails 错误吗?如何强制正确的回调每个操作只触发一次?
class Blog
has_many :posts
has_many :images
accepts_nested_attributes_for :posts
after_update :destory_existing_images, if: -> { images.any? }
after_commit :create_images, on: [:update, :create], if: -> { images.none? }
private
def destory_existing_images
images.destroy_all
end
def create_screenshots
images.create!(tag: title)
end
end
如果使用单独的回调会更好。使用 after_create_commit
进行初始化并使用 after_update_commit
更新图像。
您还可以在更新图像之前检查标题是否已更改。 Dirty API 非常适合,您的情况看起来像 if: -> { images.any? && saved_change_to_title? }
。
解决方案
class Blog
has_many :posts
has_many :images
accepts_nested_attributes_for :posts
after_create_commit :create_images, if: -> { images.none? }
after_update_commit :update_images, if: -> { images.any? && saved_change_to_title? }
private
def update_images
images.destroy_all
images.create!(tag: title)
end
def create_images
images.create!(tag: title)
end
end
当我创建一个 Blog
对象时,create
和 update
回调都会按顺序触发。
在这种情况下,更新 Blog
对象会删除所有现有的 images
并生成新的对象。我只想在 create
上生成新的 images
,并在 update
上删除并重新创建它们。
我认为这是由于 accepts_nested_attributes_for
中的嵌套对象造成的,但我似乎找不到可行的替代方法。
这是 Rails 错误吗?如何强制正确的回调每个操作只触发一次?
class Blog
has_many :posts
has_many :images
accepts_nested_attributes_for :posts
after_update :destory_existing_images, if: -> { images.any? }
after_commit :create_images, on: [:update, :create], if: -> { images.none? }
private
def destory_existing_images
images.destroy_all
end
def create_screenshots
images.create!(tag: title)
end
end
如果使用单独的回调会更好。使用 after_create_commit
进行初始化并使用 after_update_commit
更新图像。
您还可以在更新图像之前检查标题是否已更改。 Dirty API 非常适合,您的情况看起来像 if: -> { images.any? && saved_change_to_title? }
。
解决方案
class Blog
has_many :posts
has_many :images
accepts_nested_attributes_for :posts
after_create_commit :create_images, if: -> { images.none? }
after_update_commit :update_images, if: -> { images.any? && saved_change_to_title? }
private
def update_images
images.destroy_all
images.create!(tag: title)
end
def create_images
images.create!(tag: title)
end
end