1

我有这个简单的模型:

class Post < ApplicationRecord

    after_create_commit :process
    before_save :re_process, on: :update

    has_one :processed, class_name: 'Post::Process'

    def process
        self.processed.destroy if self.processed
        processed = self.build_processed
        processed.save!
    end

    private

    def re_process
        self.process if self.title_changed?
    end

end

每次Stack level to deep创建新的Post.

现在,当我删除before_save :re_process, on: :update一切工作正常。

这条线不应该只在我更新帖子时生效吗?

4

2 回答 2

8

是的,您添加的 before_saveupdate工作正常。

问题是您拥有该after_create_commit代码在创建记录后保存记录。

def process
  # here the Post was already created
  self.processed.destroy if self.processed
  processed = self.build_processed
  processed.save! # And here, you are updating the Post, so it triggers the re_process
end

所以,基本上,当你创建一个帖子时:

  1. 保存帖子

  2. 调用process回调(after_create_commit)

  3. 调用re_process(因为它process在做的时候在方法中调用save!

  4. 再次调用process(因为它被调用re_process

  5. 等等...

这个循环导致Stack level to deep

希望它有所帮助!

于 2017-09-19T15:38:19.410 回答
1

on: :update or on: :create不适合before_save

为此,您必须使用before_update

class Post < ApplicationRecord

    after_create_commit :process
    before_update :re_process

    has_one :processed, class_name: 'Post::Process'

    def process
        self.processed.destroy if self.processed
        processed = self.build_processed
        processed.save!
    end

    private

    def re_process
        self.process if self.title_changed?
    end

end

如果您使用on带有选项的选项before_save,则无论on选项中指定什么,都会执行回调。

希望这可以帮助

于 2017-09-19T17:24:29.460 回答