我正在升级从 3.2 继承到 4.0.1 的 Rails 应用程序。我在这里完成了边缘指南:
http://edgeguides.rubyonrails.org/upgrading_ruby_on_rails.html#upgrading-from-rails-3-2-to-rails-4-0
除了一个我似乎无法找到根本原因的错误之外,我已经修复了所有问题。当我尝试保存 User 模型对象时,遇到以下错误:
[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 和 rals
4.0.1 已安装。我使用 chgems 并清除了我的 .gem/
目录和 Gemfile.lock
在再次捆绑之前。这是一个 Gist of the User model.
和 here is all of the backtrace output我可以从
pry
得到.这是一个 link to the User table schema .
最佳答案
一旦你发现有问题的回调是这个:
before_create :activate_license
def activate_license
self.active_license = true
self.licensed_date = Time.now
end
事情开始变得清晰起来。
activate_licence
是之前的回调。之前回调可以halt the whole callbacks chain by returning false
(或引发异常)。如果我们仔细查看您通过手动添加一些
puts
提供的调试输出在 Rails 回调代码中,我们确实可以找到这个回调结果与 false 的比较(here - 我删除了代码的一些不重要的部分):result = activate_license
halted = (result == false)
if halted
halted_callback_hook(":activate_license")
end
因为通过返回
false
支持在回调之前暂停(即上面显示的 Rails 代码)实际上没有改变 Rails 3.2至 Rails 4.0.1 ,问题一定在于比较本身。回调返回
DateTime
对象(它是方法中的最后一个赋值,也返回)。而且,确实,DateTime
的比较s 在两个 Rails 版本之间发生了显着变化(还要注意 ==
运算符通常是 evaluated using the <=>
operator ):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
. def <=>(other)
super other.to_datetime
end
→ 全部 健全性检查没有了 !
现在,一切都清楚了:使用
DateTime
比较回调的结果(一个 <=>
对象)。运营商 false
在 Rails 4.0 下,比较尝试转换 false
反对 DateTime
没有任何健全性检查,这当然会失败并抛出异常。要解决此问题,只需确保您的回调 返回 Rails 可以与
false
比较的东西没有任何问题 ,例如true
,因为您的回调永远不应该停止链: def activate_license
self.active_license = true
self.licensed_date = Time.now
true
end
现在一切都应该再次按预期工作。
关于ruby-on-rails - Rails 3.2 到 4.0 升级 : Undefined method to_datetime for false:FalseClass,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36805639/