【问题标题】:Rails 3.2 Uniqueness validation raises undefined method 'zero?' for nil:NilclassRails 3.2 唯一性验证引发未定义的方法“零?”为 nil:Nilclass
【发布时间】:2012-02-15 07:38:01
【问题描述】:

我使用的是 Rails 3.2.0。

我有一个简单的模型,如下所示

class Favorite < ActiveRecord::Base

  validates :lst, :presence => true
  validates :uuid, :presence => true, :uniqueness => {:scope => :lst}                                                                                                                                                                    
end

如果我试试这个

f = Favorite.new
f.valid?

我收到以下错误消息:

NoMethodError: undefined method `zero?' for nil:NilClass
    from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.0/lib/active_record/associations/alias_tracker.rb:28:in `aliased_name_for'
    from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.0/lib/active_record/associations/join_dependency.rb:17:in `initialize'
    from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.0/lib/active_record/relation/finder_methods.rb:219:in `new'
    from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.0/lib/active_record/relation/finder_methods.rb:219:in `construct_join_dependency_for_association_find'
    from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.0/lib/active_record/relation/finder_methods.rb:192:in `exists?'
    from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activerecord-3.2.0/lib/active_record/validations/uniqueness.rb:32:in `validate_each'
    from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activemodel-3.2.0/lib/active_model/validator.rb:153:in `block in validate'
    from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activemodel-3.2.0/lib/active_model/validator.rb:150:in `each'
    from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activemodel-3.2.0/lib/active_model/validator.rb:150:in `validate'
    from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.2.0/lib/active_support/callbacks.rb:310:in `_callback_before_15'
    from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.2.0/lib/active_support/callbacks.rb:429:in `_run__1275595979440079611__validate__42615372200132002__callbacks'
    from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.2.0/lib/active_support/callbacks.rb:405:in `__run_callback'
    from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.2.0/lib/active_support/callbacks.rb:385:in `_run_validate_callbacks'
    from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activesupport-3.2.0/lib/active_support/callbacks.rb:81:in `run_callbacks'
    from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activemodel-3.2.0/lib/active_model/validations.rb:212:in `run_validations!'
    from /Users/ragrawal/.rvm/gems/ruby-1.9.2-p290/gems/activemodel-3.2.0/lib/active_model/validations/callbacks.rb:53:in `block in run_validations!'
....
....

【问题讨论】:

  • 仅此而已?架构是什么样的?
  • 我在 alias_tracker 中遇到了同样的错误,我相信这是一个 Rails 类,它使 AREL 在构建连接时能够使用不冲突的表名。 OP,你能发布更多关于你在做什么的细节吗?我正在使用 Rails 3.2、Ruby 1.9.3 p125、MySQL 5.5、Ubuntu 11.10。

标签: ruby-on-rails validation unique


【解决方案1】:

ActiveRecord AREL 表别名中断

该错误可能是由于 ActiveRecord AREL 丢失了如何对空数组求和。

相关的代码行在文件 alias_tracker.rb 中:

 count.sum

如果 count 是一个空数组,那么该行的计算结果为:

 [].sum

在失败的 Ruby 中:

 $ irb
 > [].sum
 NoMethodError: undefined method `sum' for []:Array

Rails ActiveSupport Enumerable#sum

在 Rails 中成功,因为 ActiveSupport 正在创建 Enumerable#sum

 $ irb
 > require 'active_support/core_ext/enumerable'
 > [].sum  
 => 0

您的问题可能是您的应用程序的某些不相关区域也在创建 Enumerable#sum 或 Array#sum。不相关的代码正在覆盖 Rails 方法。

这可能发生在您的代码或不相关的 gem 中。 Rails gem 会提前加载,通常首先在您的 Gemfile 中加载,而任何稍后的 gem 都可能会干扰 Rails。

如何解决?

您是否编写了一个名为 sum 的方法,可能在一个名为 Enumerable 或 Array 的模块中?如果是这样,那是一个很好的起点。您可以重命名您的方法,或者您可以尝试更改您的方法以匹配 Rails 方法,方法是用以下代码替换您的#sum 代码:​​

module Enumerable
  def sum(identity = 0, &block)
    if block_given?
      map(&block).sum(identity)
    else
      inject(:+) || identity
    end
  end
end

如果您没有在代码中编写名为 sum 的方法,那么冲突很可能在您正在使用的 gem 中。尝试注释掉您正在使用的 gem,然后重新加载您的应用程序。

您可以搜索一个定义名为 sum 的方法的 gem,如下所示:

$ cd /usr/lib/ruby/gems 
$ find | xargs grep "def sum\b"

您是否在使用任何名为 Sixarm 的宝石?如果是这样,请与我联系,我会为您修复它们。这些是我写的,其中一些确实定义了#sum 以用于统计工具和实用程序。

希望这会有所帮助。如果它解决了您的问题,您可以在这里发布吗?

【讨论】:

  • 我在使用 descriptive_statistics gem 时遇到了这个问题,因为它定义了一个 sum 方法。谢谢你的建议!
  • descriptive_statistics 也妨碍了我,让 Gemfile 行读取 gem 'descriptive_statistics', :require => 'descriptive_statistics/safe' 然后使用 obj.extend(DescriptiveStatistics)您想在其上使用 gem 功能的对象。
  • 我有一个个人库,在我使用 ActiveSupport 时定义了 Array#sum,但是当我使用时,它就搞砸了。 我将我的方法更改为返回super rescue inject(:+)
猜你喜欢
  • 2012-09-24
  • 2014-01-06
  • 1970-01-01
  • 2012-03-15
  • 2016-09-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-06
相关资源
最近更新 更多