Kri*_*rma 21 ruby activerecord callback ruby-on-rails-3
Class User
before_save :set_searchable
def set_searchable
self.searchable = true if self.status == :active
end
end
>> u = User.last
>> u.save
false
Run Code Online (Sandbox Code Playgroud)
u.save总是返回false.如果我删除before_save它也有效,如果我在before_save中返回true它是有效的
所以我需要在before_save中给出return语句吗?如果before_save返回false,ActiveRecord会保存一个对象吗?
我在哪里可以看到有关回调及其工作流程的完整文档.
提前致谢
noo*_*odl 32
来自:http://api.rubyonrails.org/classes/ActiveRecord/Callbacks.html
如果before_*回调返回false,则取消所有后续回调和相关操作.如果after_*回调返回false,则取消所有后续回调.回调通常按照定义的顺序运行,但回调定义为模型上的方法(最后调用).
所以,是的.
mah*_*off 20
不,您不需要从Rails回调中返回true.您可以根本不返回任何内容,或者返回true,或3.141592,它仍然会被保存.唯一重要的是如果你返回false,这只适用于Rails 5之前.返回false将取消Rails之前的保存5.返回true从未产生任何影响.
对于Rails 5+,阻止更新的新方法是抛出异常:throw(:abort)
..这更直观,更不容易出错.除非您配置遗留行为,否则返回值对它是否将保存没有影响.
这是有效的 - 并且非常好的干练习 - 只是继续你的业务,而不是回报任何东西; 如果使用早期的Rails,请确保避免意外地返回false.例如:
# This is fine, record will be saved
def before_save
self.foo = 'bar' # Implicitly returns 'bar'
end
# This is an accidental veto, record will not be saved
def before_save
Rails.logger.info 'user requested save'
self.fresh = false # Oops! Implicitly returns false
end
# One way to rectify the above example (another would be to re-order if it's possible)
def before_save
Rails.logger.info 'user requested save'
self.fresh = false
return # Implicitly returns nil. Could also do `return true`
end
Run Code Online (Sandbox Code Playgroud)
这里的问题是你可能会忘记一些"程序"类型函数会将布尔值作为一种状态代码返回,或者仅仅因为实现恰好以布尔值作为副作用而结束.你可能会认为你正在改变字符串或其他东西,但最终会不小心否决回调.因此,虽然我认为从回调中显式返回通常太嘈杂,但您需要注意隐式返回.人们主张回归真实的一个原因是要防范这种问题.