Проблема с передачей boolean на update_attributes
У меня есть следующая модель:
class GuestCatering < ActiveRecord::Base
# Validation
validates :name, :presence => true
validates :order_number, :presence => true
validates :orderable, :presence => true
end
Но когда я попытаюсь обновить существующий GuestCatering с помощью следующего кода:
guest_catering.update_attributes(:orderable => false)
Переменная гостевого питания является действительным объектом GuestCatering.
Объект guest_catering имеет ошибки после обновления, например:
<{[:orderable, ["can't be blank"]]=>nil}>
Но когда я передаю orderable => true
, все в порядке и ошибок.
Что здесь не так, почему я не могу установить false?
Ответы
Ответ 1
Ваша модель действительно ведет себя точно так же, как вы сказали ей, используя ваше использование validates :orderable, :presence => true
Здесь мало смысла проверять наличие логического флага - он будет true
, nil
или false
- и в мире Ruby nil и false имеют одинаковое семантическое значение, когда дело доходит до логической логики.
Внутренне, validates :presence
полагается на значение проверяемого атрибута, чтобы возвращать false
, когда вызывается blank?
. И в Rails (с ActiveSupport) false.blank?
оценивается как true
- это означает, что ваше поле не выполняет проверку.
Просто удалите эту проверку и все будет работать, как ожидалось.
Ответ 2
Как сказал в своем ответе Дэн Чейль, булевский nil
и false
семантически то же самое.
Но если вам действительно нужно его проверить (не разрешая nil
), вы всегда можете:
validates_inclusion_of :orderable, :in => [true, false]
Ответ 3
Вместо validates :presence => :true
вы должны написать свои миграции со значением по умолчанию следующим образом:
t.boolean :orderable, :default => 0
Я предполагаю, что ваше значение по умолчанию должно быть false
. Если true
, по умолчанию используется 1. Затем он установит значение по умолчанию в базе данных. Таким образом, вы можете опустить проверку валидации.
Причиной, по которой вы не можете использовать validates :presence
, отвечает @dan. Присутствие означает не пустое и Rails использует для этого .blank?
функцию, а false.blank?
- true