Подтвердить что ты не робот

Понимание проверки правильности: что делает 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 делает эту магию?

4b9b3361

Ответ 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" (потому что проверка уникальности не будет выполняться, когда электронное письмо будет пустым).