Rails:before_save - 堆栈级别太深
Posted
技术标签:
【中文标题】Rails:before_save - 堆栈级别太深【英文标题】:Rails: before_save - Stack level too deep 【发布时间】:2017-09-19 15:16:40 【问题描述】:我有这个简单的模型:
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
每次创建新的Post
时都会收到Stack level to deep
错误。
现在,当我删除 before_save :re_process, on: :update
时,一切正常。
这条线不应该只在我更新帖子时生效吗?
【问题讨论】:
【参考方案1】:是的,您在 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
所以,基本上,当你创建一个帖子时:
保存帖子
调用process
回调(after_create_commit)
调用re_process
(因为它在process
方法中调用时
做save!
)
再次调用process
(因为在re_process
中调用)
等等……
这个循环导致Stack level to deep
希望对您有所帮助!
【讨论】:
3.步骤:到底为什么保存processed
会导致before_save
触发self
(帖子)?
不应该before_save
只被self.save!
触发吗?
@ariel on: :update or on: :create
在 before_save 上不起作用为此,您必须使用 before_update【参考方案2】:
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
选项中指定什么,都会执行回调。
希望对你有帮助
【讨论】:
工作,谢谢!这就是我想要完成的:) 很高兴为您提供帮助以上是关于Rails:before_save - 堆栈级别太深的主要内容,如果未能解决你的问题,请参考以下文章
带有 MD5 摘要的 Rails 模型 before_save