before_validation,on :: save vs before_save

时间:2013-04-30 09:24:30

标签: ruby-on-rails activerecord

假设我有一个模型,我可能需要在保存之前操作它的一些属性:

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}}。

任何强烈的意见?

3 个答案:

答案 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。