In your code, :presence =>
and :uniqueness =>
are validators, while :allow_blank =>
is a default option that gets passed to other validators.
So your code:
validates(
:email,
:presence => true,
:allow_blank => true,
:uniqueness => { :case_sensitive => false }
)
Is equivalent to this code:
validates(
:email,
:presence => { :allow_blank => true },
:uniqueness => { :allow_blank => true, :case_sensitive => false }
)
However, the presence
validator ignores the allow_blank
option, so your code ends up being essentially this:
validates(
:email,
:presence => { }, # `{ }` is equivalent to `true`
:uniqueness => { :allow_blank => true, :case_sensitive => false }
)
Having :allow_blank => true
in :uniqueness
means that when the email is blank, the uniqueness
validation will not be run.
One effect of this is that you eliminate a DB query.
E.g., without the :allow_blank => true
condition you would see this:
>> user = User.new(email: nil)
>> user.valid?
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE "users"."name" IS NULL LIMIT 1
=> false
>> user.errors.messages
=> {:email=>["can't be blank"]}
But with the :allow_blank => true
option you won't see that User Exists
DB query happen.
Another edge-case side effect happens when you have a record with a blank email address in your DB already. In that case if you don't have the :allow_blank => true
option on the uniqueness
validator, then you'll see two errors come back:
>> user = User.new(email: nil)
>> user.valid?
User Exists (0.2ms) SELECT 1 AS one FROM "users" WHERE "users"."name" IS NULL LIMIT 1
=> false
>> user.errors.messages
=> {:email=>["has already been taken", "can't be blank"]}
But with the :allow_blank => true
option you'll only see the "can't be blank"
error (because the uniqueness validation won't run when the email is blank).