【问题标题】:Ruby Undefined method downcaseRuby 未定义方法小写
【发布时间】:2013-09-19 18:07:17
【问题描述】:

我在以下代码中遇到异常。谁能告诉我我做错了什么,以及如何防止它?

def self.find_by_data(data = {})
            where(name_canonical: data['name'].downcase.gsub(/\s+/, ''),
                  fuel:           data['fuel'],
                  trim_canonical: data['trim'].downcase.gsub(/\s+/, ''),
                  year:           data['year']).first
        end

例外:

/Users/charlie/Documents/WIP/projectx/ar_models.rb:35:in `find_by_data': undefined method `downcase' for nil:NilClass (NoMethodError)ooooooooooooooooooooooooo| ETA:   0:00:00
    from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/relation/delegation.rb:36:in `block in find_by_data'
    from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/associations/collection_proxy.rb:845:in `block in scoping'
    from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/relation.rb:270:in `scoping'
    from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/associations/collection_proxy.rb:845:in `scoping'
    from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/relation/delegation.rb:36:in `find_by_data'
    from /Users/charlie/Documents/WIP/projectx/ar_models.rb:132:in `create_or_assign_existing'
    from /Users/charlie/Documents/WIP/projectx/app.rb:230:in `block (2 levels) in work'
    from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/activerecord-4.0.0/lib/active_record/connection_adapters/abstract/connection_pool.rb:294:in `with_connection'
    from /Users/charlie/Documents/WIP/projectx/app.rb:80:in `block in work'
    from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:319:in `call'
    from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:319:in `call_with_index'
    from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:179:in `block (3 levels) in work_in_threads'
    from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:326:in `with_instrumentation'
    from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:177:in `block (2 levels) in work_in_threads'
    from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:171:in `loop'
    from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:171:in `block in work_in_threads'
    from /Users/charlie/.rvm/gems/ruby-2.0.0-p0/gems/parallel-0.6.3/lib/parallel.rb:62:in `block (2 levels) in in_threads'

【问题讨论】:

  • 我们不知道您的哈希data 包含什么。但很明显data['name']data['trim'] 包含nil。检查相同

标签: ruby exception gsub


【解决方案1】:

当您看到“nil:NilClass 的未定义方法 ...”时,这意味着您有一个 nil 值,您正在尝试调用该方法。

在这种情况下,data['name'] 之类的东西没有定义。

为了使这更加防弹:

data['name'].to_s.downcase.gsub(/\s+/, '')

这会将所有内容转换为字符串以开始。 nil.to_s默认为空字符串,所以安全。

【讨论】:

    【解决方案2】:

    也许使用三元运算符:

    def self.find_by_data(data = {})
                where(name_canonical: data['name'] == nil ? '' : data['name'].downcase.gsub(/\s+/, ''),
                      fuel:           data['fuel'],
                      trim_canonical: data['trim'] == nil ? '' : data['name'].downcase.gsub(/\s+/, ''),
                      year:           data['year']).first
            end
    

    【讨论】:

    • == nil 非常丑陋。更好的选择是.nil?,但前提是该值可能是false。在这种情况下更好的是:data['name'] ? data['name'].downcase.gsub(...) : ''
    • @tadman 然而这是一个解决方案。请问有更好的吗?我们必须去追has_key?吗?但是nil 是否仍然可以做到这一点并且我们必须再次检查?
    • 我已经发布了我自己的观点,其中涉及to_s,它强制将值转换为字符串,无论它是否为nil。 99% 的情况下,x == nil 可以替换为 !x,或者在这种情况下,只需反转三进制即可。
    • 现在这对我来说很难看。
    • 和你的一样,减去== nil,倒转逻辑。
    【解决方案3】:

    你的

    data['name'] 
    

    data['trim']
    

    是零。 检查您的输入数据。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-25
      • 2012-03-13
      • 2010-10-15
      • 1970-01-01
      • 1970-01-01
      • 2013-03-07
      • 2018-05-16
      • 1970-01-01
      相关资源
      最近更新 更多