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

Update callback running after create via Accepts Nested Attributes - Rails

提问人:Kobius 提问时间:4/29/2022 更新时间:4/29/2022 访问量:294

问:

当我创建一个对象时,和 回调都是按顺序触发的。Blogcreateupdate

在这种情况下,更新对象将删除所有现有对象并生成新对象。我只想在 上生成新的,然后在 上删除并重新创建它们。Blogimagesimagescreateupdate

我认为这是由于嵌套对象 ,但我似乎找不到可行的替代方案。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
Ruby-on-Rails Ruby PostgreSQL 嵌套 回调

评论


答:

1赞 Christos-Angelos Vasilopoulos 4/29/2022 #1

如果使用单独的回调会更好。用于初始化和更新映像。after_create_commitafter_update_commit

您还可以在更新图像之前检查标题是否更改。肮脏的 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

评论

0赞 Kobius 4/30/2022
这是一个美丽的补充,谢谢 - 这很完美!saved_change_to_title?