2013-03-12 58 views
1

我有一个关于this test from the Michael Hartl tutorial问题:电子邮件唯一性验证程序何时被触发?

型号:

class User < ActiveRecord::Base 
    . 
    . 
    . 
    validates :email, presence: true, format: { with: VALID_EMAIL_REGEX }, 
        uniqueness: true 
end 

测试:

require 'spec_helper' 

describe User do 

    before do 
    @user = User.new(name: "Example User", email: "[email protected]") 
    end 
    . 
    . 
    . 
    describe "when email address is already taken" do 
    before do 
     user_with_same_email = @user.dup 
     user_with_same_email.email = @user.email.upcase 
     user_with_same_email.save 
    end 

    it { should_not be_valid } 
    end 
end 

我的电子邮件中的唯一性验证的理解是,它不能被添加在数据库中两次。但在这个测试中,用户只是用一个新的而不是一个创建实例化的。

因此,这里就是我的想法发生了:

  • @user = User.new(只在内存中)
  • ...
  • user_with_same_email = @user.dup我们在内存
  • 两个用户...
  • user_with_same_email.save我们将第一个用户插入数据库,所以它应该是有效的,但测试it { should_not be_valid }通过。

我得到了什么问题?

回答

1

真正发生:

before

  • @user = User.new(只在内存中)

describe

  • user_with_same_email = @user.dup我们在内存中有两个用户
  • user_with_same_email.save我们在db中插入第一个用户,所以它应该是有效的,它是!但是,这并不是什么正在这里

测试在it

  • should_not be_valid呼吁.valid?上@user,因为我们刚刚插入同一个电子邮件的用户,@user无效。测试通过。
+0

好答案!同样重要的是要注意,在对数据库的INSERT命令非常快的情况下,它们都会在内存中传递验证,因此两者都将被“插入”。正如这里讨论http://stackoverflow.com/questions/14942608/ruby-on-rails-activerecord-uniqueness-validation – lllllll 2013-09-05 18:18:57