Недействительный срок службы Rails по модели приводит к нулю
У меня есть модель с атрибутом datetime. Я пытаюсь проверить входящий JSON, который будет обновлять модель. Но ActiveRecord, по-видимому, устанавливает значение атрибута в nil, если это недопустимое datetime. Я не могу ответить соответствующей ошибкой, потому что атрибуту разрешено быть nil. Что я делаю неправильно?
код:
class DatetimeValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
value.to_datetime rescue record.errors[attribute] << (options[:message] || "must be a date.")
end
end
class Foo
# column :my_date, :datetime
validates :my_date, :allow_nil => true, :datetime => true
end
Консоль:
1.9.3p125 :001 > x = Foo.new
=> #<Foo id: nil, my_date: nil>
1.9.3p125 :001 > x.my_date = 'bad value'
=> 'bad value'
1.9.3p125 :001 > x.my_date
=> nil
1.9.3p125 :001 > x.valid?
=> true
Что касается ActiveRecord, установка атрибута datetime в "bad_value" эквивалентна установке его на нуль, поэтому я не могу его проверить, так как my_date не требуется. Мне это кажется ошибкой. Какое лучшее обходное решение?
Спасибо!
Ответы
Ответ 1
Одним из способов было бы переместить часть allow_nil
в проверку date_time
:
class DatetimeValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
return if value.blank?
value.to_datetime rescue record.errors[attribute] << (options[:message] || "must be a date.")
end
end
class Foo
validates :my_date, :datetime => true
end
Изменить: я думаю, что это проблема с typecasting - попробуйте это (адаптировано из кода для validates :numericality
):
def validate_each(record, attribute, value)
before_type_cast = "#{attribute}_before_type_cast"
raw_value = record.send(before_type_cast) if record.respond_to?(before_type_cast.to_sym)
raw_value ||= value
return if raw_value.blank?
raw_value.to_datetime rescue record.errors[attribute] << (options[:message] || "must be a date.")
end