2013-09-19 1 views
3

Я получаю исключение в следующем фрагменте кода. Может кто-нибудь, пожалуйста, скажите мне, что я делаю неправильно, и как я могу это предотвратить?Ruby Undefined method downcase

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' 
+0

Мы не знаем, что содержат ваши хэш-данные. Но очень ясно, что либо 'data ['name']', либо 'data ['trim']' содержит 'nil'. Проверьте то же самое –

ответ

12

Когда вы видите "неопределенный метод ... для ноль: NilClass" это означает, что у вас есть значение nil вы находитесь пытается вызвать метод.

В этом случае что-то вроде data['name'] не определено.

Чтобы сделать это более пуленепробиваемые:

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

Это превращает все в строку, чтобы начать с. nil.to_s - пустая строка по умолчанию, поэтому она безопасна.

0

Использование тройные oprators возможно:

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 
+0

'== nil' в высшей степени уродливое. Лучшей альтернативой является «.nil?», Но только если это значение может быть «ложным». Еще лучше в этом случае: 'data ['name']? data ['name']. downcase.gsub (...): '' ' – tadman

+0

@tadman Тем не менее это решение. Лучше, пожалуйста? Должны ли мы идти после 'has_key?'? Но разве «нет» все еще возможно для этого, и что мы должны снова проверить? – konsolebox

+0

Я отправил свой собственный запрос, который включает в себя 'to_s', который заставляет значение для строки, независимо от того, является ли это' nil' или нет. 99% времени 'x == nil' могут быть заменены на'! X' или в этом случае, просто изменяя тройку. – tadman

0

Ваш

data['name'] 

или

data['trim'] 

является нулевым. Проверьте свои входные данные.