2017-09-19 52 views
1

我有這個簡單的模型:的Rails:before_save - 堆棧層次過深

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一切工作正常。

不應該只在我更新帖子時影響這條線嗎?

回答

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選項。

希望這有助於

+0

Works,謝謝!這就是我試圖完成:) – jonhue

+0

很高興幫助你 –

8

是的,您在update上添加的before_save工作正常。

問題是你有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

希望它幫助!

+0

3步:爲什麼在地球上節約'processed'導致觸發''爲self'(後)before_save'? – jonhue

+0

不應''before_save'只能由'self.save!'觸發嗎? – jonhue

+0

@ariel'on::update或on :: create' does not work before_save 爲此,您必須使用before_update –