我正在关注 Michael Hartl 的 RoR 教程,但在测试我的代码时出现以下错误。我似乎无法弄清楚为什么我的对象没有通过有效。
我的 user.rb 文件:
class User < ActiveRecord::Base
  before_save { |user| user.email = user.email.downcase }
  validates :name, presence: true, length: { maximum: 50 }
  VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
  validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
                    uniqueness: { case_sensitive: false }
end
这是我的 user_rspec.rb:
    require 'spec_helper'
describe User do
  before { @user = User.new(name: "bobo", email: "user@example.com")  }
  subject { @user }
  it { should respond_to(:name) }
  it { should respond_to(:email) }
  it { should be_valid }
  describe "when name is not present" do
    before { @user.name = " "}
    it { should_not be_valid}
  end
  describe "when email is not present" do
    before { @user.email = " "}
    it { should_not be_valid}
  end
  describe "when name is too long" do
    before { @user.name = "a" * 51}
    it { should_not be_valid}
  end
  describe "when email format is invalid" do
    it "should be invalid" do
      addresses = %w[user@foo,com user_at_foo.org example-user@foo.]
      addresses.each do |invalid_address|
        @user.email = invalid_address
        @user.should_not be_valid
      end
    end
  end
  describe "when email format is valid" do
    it "should be valid" do 
      addresses = %w[user@foo.COM A_US-ER@f.b.org frst.lst@foo.jp a+b@baz.cn]
      addresses.each do |valid_address|
        @user.email = valid_address
        @user.should be_valid
      end
    end
  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
当我运行我的测试时,我收到以下错误:失败:
  1) User 
     Failure/Error: it { should be_valid }
       expected valid? to return true, got false
     # ./spec/models/user_spec.rb:12:in `block (2 levels) in <top (required)>'
Finished in 0.21355 seconds
9 examples, 1 failure
Failed examples:
rspec ./spec/models/user_spec.rb:12 # User `
当我在 Rails 控制台中运行 user_with_same_email.errors 时,我得到以下答案:
ruby-2.0.0-p247 :001 > user = User.new(name: "bobo", email: "user@example.com")
 => #<User id: nil, name: "bobo", email: "user@example.com", created_at: nil, updated_at:     nil> 
ruby-2.0.0-p247 :002 > user_with_same_email =  user.dup
 => #<User id: nil, name: "bobo", email: "user@example.com", created_at: nil, updated_at: nil> 
ruby-2.0.0-p247 :003 > user_with_same_email.valid?
  User Exists (0.1ms)  SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") =     LOWER('user@example.com') LIMIT 1
 => true 
ruby-2.0.0-p247 :004 > user_with_same_email.errors
 => #<ActiveModel::Errors:0x007fad6491f780 @base=#<User id: nil, name: "bobo", email:    "user@example.com", created_at: nil, updated_at: nil>, @messages={}> 
ruby-2.0.0-p247 :005 >
如您所见,该错误未传递任何消息。
有人知道我该如何解决这个错误吗?
谢谢!
添加:
当我尝试使用已保存的电子邮件保存用户时,似乎出现了错误。
$ rails console --sandbox
Loading development environment in sandbox (Rails 4.0.0)
Any modifications you make will be rolled back on exit
ruby-2.0.0-p247 :001 > user = User.new(name: "bobo", email: "user@example.com")
 => #<User id: nil, name: "bobo", email: "user@example.com", created_at: nil, updated_at:         nil> 
ruby-2.0.0-p247 :002 > user.save
   (0.1ms)  SAVEPOINT active_record_1
  User Exists (0.2ms)  SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") =     LOWER('user@example.com') LIMIT 1
  SQL (3.3ms)  INSERT INTO "users" ("created_at", "email", "name", "updated_at") VALUES       (?, ?, ?, ?)  [["created_at", Wed, 16 Oct 2013 10:15:19 UTC +00:00], ["email",     "user@example.com"], ["name", "bobo"], ["updated_at", Wed, 16 Oct 2013 10:15:19 UTC +00:00]]
   (0.1ms)  RELEASE SAVEPOINT active_record_1
 => true 
    ruby-2.0.0-p247 :003 > user_with_same_email =  user.dup
 => #<User id: nil, name: "bobo", email: "user@example.com", created_at: nil, updated_at: nil> 
ruby-2.0.0-p247 :004 > user_with_same_email.save
   (0.1ms)  SAVEPOINT active_record_1
  User Exists (0.1ms)  SELECT 1 AS one FROM "users" WHERE LOWER("users"."email") = LOWER('user@example.com') LIMIT 1
   (0.1ms)  ROLLBACK TO SAVEPOINT active_record_1
 => false 
ruby-2.0.0-p247 :005 > 
我不确定为什么会发生这种情况。我的验证不应该解决这个问题吗?
谢谢!