Понимание проверки правильности: что делает allow_blank?
Я новичок в Rails и нашел небольшой фрагмент для проверки присутствия и уникальности шаг за шагом: сначала проверьте наличие, затем проверьте уникальность.
validates :email, :presence => true, :allow_blank => true, :uniqueness => { :case_sensitive => false }
Я немного запутался в использовании presence => true
и allow_blank => true
вместе.
Без использования allow_blank => true
оба правила будут проверяться одновременно, а не шаг за шагом.
Почему allow_blank => true
делает эту магию?
Ответы
Ответ 1
То, что у вас есть, эквивалентно этому (завернутый для ясности):
validates :email, :presence => true,
:uniqueness => { :allow_blank => true, :case_sensitive => false }
Это немного глупо, хотя, если вам нужно присутствие, то это приведет к "аннулированию" предложения: allow_blank: уникальность.
Это имеет смысл, когда вы переключаетесь на использование других валидаторов.. говорите... формат и уникальность, но вы не хотите никаких проверок, если он пуст. В этом случае добавление "глобально применяется": allow_blank имеет больше смысла и немного СУЩЕСТВУЕТ код.
Это...
validates :email, :format => {:allow_blank => true, ...},
:uniqueness => {:allow_blank => true, ...}
можно записать так:
validates :email, :allow_blank => true, :format => {...}, :uniqueness => {...}
Ответ 2
Следующее различие может быть полезно знать:
presence: true # nil and empty string fail validation
presence: true, allow_blank: true # nil fails validation, empty string passes
Ответ 3
:allow_blank
- это опция, которая "отключит" несколько из валидаторов, но не проверку валидатора. Результатом использования этих двух компонентов является то, что когда поле остается пустым, вы получите сообщение об ошибке :blank
(т.е. "Не может быть пустым" ), но не другие сообщения об ошибках.
Ответ 4
из аннотации Rails
# * <tt>:allow_nil</tt> - Skip validation if the attribute is +nil+.
# * <tt>:allow_blank</tt> - Skip validation if the attribute is blank.
поэтому это означает, что при использовании allow_blank
по электронной почте, если письмо равно нулю, только одна ошибка добавлена в объект errors
, перескакивает проверка уникальности.
Ответ 5
Слишком много объяснений, просто усложняют простые вещи, скажем так:
# do not use this validates to check if the value is blank
Ответ 6
В вашем коде :allow_blank =>
:presence =>
и :uniqueness =>
являются валидаторами, а :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
, поэтому ваш код в конечном итоге 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"
(потому что проверка уникальности не будет выполняться, когда электронное письмо будет пустым).