Обновление Rails 3.2 до 4.0: неопределенный метод datetime для false:FalseClass
Я обновляю приложение Rails, которое я унаследовал от 3.2 до 4.0.1. Я последовал и закончил руководство края здесь:
http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html#upgrading-from-rails-3-2-to-rails-4-0
я получил все исправлено, за исключением одной ошибки, которую я не могу найти основную причину. Когда я пытаюсь сохранить объект модели пользователя, я столкнулся со следующей ошибкой:
[1] pry(main)> User.create(name: "test user", email: "testuser@frobnitz.com", password: "testPassword123", password_confirmation: "testPassword123")
(0.6ms) BEGIN
(0.9ms) ROLLBACK
NoMethodError: undefined method `to_datetime' for false:FalseClass
from /home/cmhobbs/src/serve2perform/.gem/ruby/2.3.0/gems/activesupport-4.0.1/lib/active_support/core_ext/date_time/calculations.rb:161:in `<=>'
activesupport
4.0.1-и 4.0.1 есть. Я использую chgems, и я очистил свой и Gemfile.lock
прежде чем снова связывать.
здесь суть модели пользователя.
и вот все выходные данные backtrace я мог бы получить от pry
.
2 ответов
как только вы нашли оскорбительный обратный вызов, чтобы быть этим:
before_create :activate_license
def activate_license
self.active_license = true
self.licensed_date = Time.now
end
вещи начинают проясняться. The activate_licence
это до обратный. до обратные вызовы могут остановите всю цепочку обратных вызовов, вернувшись false
(или создание исключения).
если мы внимательно посмотрим в выводе отладки, который вы предоставили, вручную добавив некоторые puts
линии в код обратного вызова Rails, мы действительно можем найдите сравнение этого результата обратного вызова с false (здесь - я удалил некоторые несущественные части кода):
result = activate_license
halted = (result == false)
if halted
halted_callback_hook(":activate_license")
end
потому что поддержка остановки перед обратными вызовами путем возврата false
(т. е. код рельсов, показанный выше) практически не изменился с рельсы 3.2 to рельсы 4.0.1, проблема должна заключаться в самом сравнении.
обратный вызов возвращает DateTime
object (это последнее назначение в метод, который также возвращается). И, действительно, сравнение DateTime
s значительно изменился между двумя версиями Rails (также обратите внимание, что ==
оператор обычно оценка <=>
оператор):
-
в Rails 3.2 это было этой:
def <=>(other) if other.kind_of?(Infinity) super elsif other.respond_to? :to_datetime super other.to_datetime else nil end end
заметьте, особенно
respond_to?
проверить, еслиother
объект также является объектом даты или времени при возврате в противном случаеnil
. -
тогда как в Rails 4.0.1 это изменено на голый код ниже:
def <=>(other) super other.to_datetime end
→ все проверки ушли!
теперь все ясно: результат обратного вызова (a все должно работать как ожидается.
вы можете связать даже в основных классах, пожалуйста, сделайте что-то вроде этого и проверьте, что other
, откуда он взялся.
/ главная / cmhobbs / src / serve2perform/.gem / ruby / 2.3.0/gems/activesupport-4.0.1/lib/active_support/core_ext/date_time / вычисления.rb
def <=>(other)
binding.pry
if other.kind_of?(Infinity)
super
elsif other.respond_to? :to_datetime
super other.to_datetime rescue nil
else
nil
end
end