在您的代码中,:presence =>
并且:uniqueness =>
是验证器,while:allow_blank =>
是传递给其他验证器的默认选项。
所以你的代码:
validates(
:email,
:presence => true,
:allow_blank => true,
:uniqueness => { :case_sensitive => false }
)
相当于这段代码:
validates(
:email,
:presence => { :allow_blank => true },
:uniqueness => { :allow_blank => true, :case_sensitive => false }
)
但是,presence
验证器会忽略该allow_blank
选项,因此您的代码最终基本上是这样的:
validates(
:email,
:presence => { }, # `{ }` is equivalent to `true`
:uniqueness => { :allow_blank => true, :case_sensitive => false }
)
输入意味着当电子邮件为空白时,:allow_blank => true
将不会运行验证。:uniqueness
uniqueness
这样做的一个效果是您消除了数据库查询。
例如,如果没有条件,:allow_blank => true
您会看到:
>> 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"]}
但是使用该:allow_blank => true
选项,您将不会看到User Exists
数据库查询发生。
当您的数据库中已有包含空白电子邮件地址的记录时,会发生另一个极端情况的副作用。在这种情况下,如果您在验证器上没有:allow_blank => true
选项uniqueness
,那么您会看到返回两个错误:
>> 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"]}
但是使用该:allow_blank => true
选项,您只会看到"can't be blank"
错误(因为当电子邮件为空白时,唯一性验证不会运行)。