Почему Rails сохраняет String как нулевой столбец времени?

Я столкнулся с этой идиосинкразией, проверяя свои проверки. С миграцией, определенной следующим образом:

create_table :time_windows do |t|
  t.datetime :window_begin, :null => true
  t.datetime :window_end, :null => true
end

в ирб

>> t = TimeWindow.new({:window_begin  => Time.now, :window_end => "not a time"})
=> #<TimeWindow id: nil, window_begin: "2010-07-29 15:54:07", window_end: nil>

Мой вопрос: почему ActiveRecord интерпретирует «не время» как nil, а не просто устанавливает :window_end = «не время»? Тот же самый перевод в ноль происходит, когда вы также устанавливаете :window_end в int.

Причина, по которой это проблема для меня, заключается в том, что если кто-то попытается сохранить значение, отличное от времени, в столбце :window_end (или :window_start), я бы хотел, чтобы возникла ошибка, но здесь это не так.

Спасибо.


person Big Bird    schedule 29.07.2010    source источник


Ответы (1)


Прежде всего, база данных не может сохранить строку в столбце даты и времени. Во-вторых, Rails интерпретирует «не время» как nil, потому что у вас нет значения времени, то есть у вас есть nil.

Наконец, вы несете ответственность за проверку вашего ввода. Вы можете сделать это примерно так: rails встроен в проверку даты и времени

person Slobodan Kovacevic    schedule 29.07.2010
comment
Я думаю, что мой вопрос был плохо сформулирован. Забудьте сохранить его в базе данных на секунду. Когда я создаю объект TimeWindow в памяти с недопустимым значением (не Time) для атрибута :window_end, он просто создает экземпляр объекта с nil для :window_end. Однако, если я создаю экземпляр другого класса модели с атрибутом :count типа integer, например, и назначаю :count =› не число, объект создается с :count = не числом. Почему перевод String -> nil в первом случае, а не во втором? - person Big Bird; 30.07.2010
comment
Это неверно для целочисленных атрибутов. Я просто сделал следующее в одном из своих проектов: u = User.new(:sign_in_count => не число) [кстати, sign_in_count — целочисленный атрибут], и когда я вызвал u.sign_in_count, я получил: 0. Причина этого в том, что не число приводится с использованием to_i, которое возвращает 0 (не число.to_i => 0) - person Slobodan Kovacevic; 30.07.2010