在尝试保存之前,Rails模型验证方法是否将当前数据作为验证过程的一部分进行检查?

时间:2012-05-17 17:47:05

标签: ruby-on-rails

我在Michael Hartl的[Rail Tutorial]第6章中看到一些RSpec代码:http://ruby.railstutorial.org/chapters/modeling-users#code:validates_uniqueness_of_email_test。编写它是为了测试用户模型的email属性的唯一性验证方法。它看起来像这样:

代码清单6.18拒绝重复电子邮件地址的测试。 (*规格/模型/ user_spec.rb *)

require 'spec_helper'

describe User do

  before do
    @user = User.new(name: "Example User", email: "user@example.com")
  end
  subject { @user }
  .
  .
  .
  describe "when email address is already taken" do
    before do
      user_with_same_email = @user.dup
      user_with_same_email.save
    end

    it { should_not be_valid }
  end
end

这是用户模型验证码:

validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
                    uniqueness: true

我的问题是:验证如何实际工作?有一个用户已将相同的电子邮件地址保存到数据库中,并且@user实例上的Rails验证在我之前恢复为无效甚至试图保存它? Rails验证器是否使用当前数据来验证用户的实例,即使它们只是存储在内存中而当前没有尝试添加到数据库中?

1 个答案:

答案 0 :(得分:2)

be_validvalid?上致电@user。这是rspec的工作原理。并valid?调用run_validations!,然后调用run_callbacks :validate。您可以通过源代码关注方法链:valid?中定义了super,并在activerecord / lib / active_record / validations.rb

中调用valid? new_record?

这是关于它是如何工作的。即使未保存,模型也可以有效或不有效。如果从未保存过(true返回:create),则会调用new_record?上的false验证。基本上,如果模型有效,则可以保存。如果已保存(:update返回{{1}}但可以包含未保存的更改),则会调用{{1}}上的验证。