通过接受嵌套属性创建后更新回调 运行 - Rails

Update callback running after create via Accepts Nested Attributes - Rails

当我创建一个 Blog 对象时,createupdate 回调都会按顺序触发。

在这种情况下,更新 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