假设我有一个模型,我可能需要在保存之前操作它的一些属性:
class User < ActiveRecord::Base
attr_accessible :name, :email
# before_validation :set_name_from_email, on: :save
# OR
# before_save :set_name_from_email
def set_name_from_email
self.name ||= email
end
end
如果我必须validates :name, presence: true
,那么当然这必须是before_validation
。但是如果(现在的代码已经存在)回调没有影响对象有效性的可能性,将它放在before_save
中会更好吗?
如果代码发生变化并且回调现在可能影响有效性,那么让所有数据在一个或另一个桶中操纵回调似乎更为简洁,但是当调用像{{{{{{{{{ 1}}。
任何强烈的意见?
答案 0 :(得分:6)
通常我会将所有数据操作放在before_save
中,因为将所有数据操作放在一个地方(保存之前)是合乎逻辑的。
但是,如果您将来在名称字段上进行验证(即使数据操作不影响有效性),您应该将数据操作放在before_validation
中,因为您不希望存储数据在验证数据x时,在数据库中使用y。
您可以在此处详细了解: http://bashar3a.com/2011/09/02/activerecord-callback-gotchas-before_save-vs-before_validate/
答案 1 :(得分:3)
由于您实际上并未验证任何内容,而是操纵属性,因此应使用before_save
回调。
自定义验证方法通常会向模型添加错误,而您的set_name_from_email
却没有这样做。
答案 2 :(得分:2)
除非您要验证自己的方法指定给“name”的值,否则您可以同时使用这两个值。
但是如果您的方法可能导致名称无效,则应使用before_validation。