My model:
class User < ActiveRecord::Base
attr_accessible :email, :password, :password_confirmation
has_many :albums, dependent: :destroy
has_secure_password
validates :email, presence: true,
uniqueness: true,
format: { with: /\A[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]+\z/ }
end
and my spec:
require 'spec_helper'
describe User do
it { should respond_to :email }
it { should respond_to :password }
it { should respond_to :password_confirmation }
it { should respond_to :albums }
it { should validate_presence_of :email }
it { should validate_uniqueness_of :email }
it { should_not allow_value('invalid@email').for(:email) }
end
This raises an exception:
1) User
Failure/Error: it { should validate_uniqueness_of :email }
ActiveRecord::StatementInvalid:
PG::Error: ERROR: null value in column "password_digest" violates not-null constraint
: INSERT INTO "users" ("created_at", "email", "password_digest", "updated_at") VALUES ($1, $2, $3, $4) RETURNING "id"
# ./spec/models/user_spec.rb:14:in `block (2 levels) in <top (required)>'
In my schema.rb I have a :null => false constraint ofcourse.
I saw some other issues but not a pull request that fixes this. Any ideas?
The validates_uniqueness_of matcher needs an instance in the database to work. If there isn't an instance, it creates one in this method.
It creates an instance of the described class (in this case User) with the given attribute (in this case :email) set, but sets no other attributes. It bypasses Rails validations with :validate => false. Of course, it can't bypass DB constraints, so it fails.
Manually creating a record should work, like so:
describe User do
# ...other tests ...
it "validates uniqueness of email" do
User.new(:password_digest => 'whatever', :email => 'something').save!(:validate => false)
should validate_uniqueness_of :email
end
end
I see. Thank you.
Most helpful comment
The
validates_uniqueness_ofmatcher needs an instance in the database to work. If there isn't an instance, it creates one in this method.It creates an instance of the described class (in this case
User) with the given attribute (in this case:email) set, but sets no other attributes. It bypasses Rails validations with:validate => false. Of course, it can't bypass DB constraints, so it fails.Manually creating a record should work, like so: