I’m looking at some RSpec code in Chapter 6 of Michael Hartl’s [Rail Tutorial]: http://ruby.railstutorial.org/chapters/modeling-users#code:validates_uniqueness_of_email_test. It was written to test the uniqueness validation method of the email attribute of the user model. It looks like this:
Listing 6.18. A test for the rejection of duplicate email addresses. (*spec/models/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
And here is the user model validation code:
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: true
My question is: How does the validating actually work? There is a user with an identical email address already saved into the database and the Rails validation on the @user instance comes back as invalid before I’ve even tried to save it? Does the Rails validator use current data to validate instances of the user even if they are just being stored in memory and not currently attempting to be added to the database?
be_validcallsvalid?on@user. It’s how rspec works. Andvalid?callsrun_validations!which in turn callsrun_callbacks :validate. You can follow the methods chain through source code:valid?is defined in activerecord / lib / active_record / validations.rb and it callssupervalid?in activemodel / lib / active_model / validations.rbThat’s about how it works. And the model can be valid or not even if it is unsaved. If it was never saved (
new_record?returnstrue) as in your case validations on:createare called. Basically if model is valid it can be saved. If it was saved (new_record?returnsfalsebut it can contain unsaved changes) validations on:updateare called.