我正在关注 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 >
我不确定为什么会发生这种情况。我的验证不应该解决这个问题吗?
谢谢!