如何对新对象的派生值运行验证?

时间:2013-01-09 17:52:03

标签: ruby-on-rails validation ruby-on-rails-3.2

我有一个模型,它有几个在创建时提供的属性。该模型还具有一些从提供的属性派生的附加属性,我也想在创建时计算这些属性。更有问题的是,我希望能够对这些派生值运行验证(因为有些输入本身是有效的,导致无效的派生值)。

问题在于,当我这样做时:

class MyClass < ActiveRecord::Base
  attr_accessible :given1, :given2, :derived

  before_validation :derivation
  validates_uniqueness_of :derived

  def derivation
    self.derived = self.given1 + self.given2
  end
end

MyClass.new(:given1 => aNumber, :given2 => otherNumber)

我总是收到错误消息,说我无法将nil添加到nil。显然self.attribute是零,直到进入验证和&amp;创作过程。

显然,我可以在稍后的阶段设置我的派生值,并添加一个适用于给定属性的自定义验证,但这需要进行两次派生,这不会非常干。

是否有其他方法可以在before_validates阶段获得已分配但尚未验证的属性?

编辑:为了澄清,我想调用MyClass.new(:given1 => aNumber, :given2 => otherNumber)并在验证检查之前计算的派生值,以便验证检查就像我调用MyClass.new(:given1 => aNumber, :given2 => otherNumber, :derived => aNumber + otherNumber)一样。问题是我似乎无法在:given1方法中访问:given2before_validations的传入值。

1 个答案:

答案 0 :(得分:1)

我编写了自己的代码片段,如下所示:

class User < ActiveRecord::Base
  attr_accessible :email, :first_name, :last_name

  validates :email, uniqueness: true

  before_validation :derivation

  def derivation
    self.email = self.first_name + self.last_name
  end
end

运行以下操作不会产生任何错误:

»  u = User.new first_name: "leo", last_name: "correa"
=> #<User:0x007ff62dd8ace0> {
                      :id => nil,
              :first_name => "leo",
               :last_name => "correa",
                   :email => nil,
              :created_at => nil,
              :updated_at => nil,
}
»  u.valid?
  User Exists (0.9ms)  SELECT 1 AS one FROM "users" WHERE "users"."email" = 'leocorrea' LIMIT 1
=> true

正在运行u.save成功保存了记录,并在重复User.new并保存该记录时使用ROLLBACK保存该记录,因为电子邮件已被使用。

在任何情况下,请确保将所使用的任何变量分配给given1,给定2,并且无论结果是什么,请确保不会给您错误,因为它将取消before_validate回调并且记录赢了“t = t保存。