2012-01-16 2 views
2

Я думаю, что понимаю, почему это происходит, но я не уверен, как решить проблему.NoMethodError: undefined method `methodname 'для # <memory location>

Я отправлю соответствующий код ниже.

class CoveragesController < ApplicationController 
    def grab 
    url = { 
     "cnn" => "http://www.cnn.com/", 
     "cnn_politics" => "http://www.cnn.com/POLITICS/", 
    } 

    url.each do |key, value| 
     data = urlToString(value) 
     appearances = countAppearances(data) 
     @coverage = Coverage.create(
     :media  => key, 
     :url   => value, 
     :content  => data, 
     :obama  => appearances["obama"], 
    ) 
    end 
    end 
end 

Какой метод захвата не так важен. Это просто метод, который использует несколько других методов для подсчета количества времени, которое «Обама» упоминается на веб-сайте CNN.

В консоли rails я попытался запустить Coverage.grab. Это сообщение об ошибке, которое я получил.

1.9.3-p0 :003 > Coverage.grab 
NoMethodError: undefined method `grab' for #<Class:0x007f9a5d813bf8> 
    from /Users/jasonkim/.rvm/gems/ruby-1.9.3-p0/gems/activerecord-3.1.3/lib/active_record/base.rb:1088:in `method_missing' 
    from (irb):3 
    from /Users/jasonkim/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.1.3/lib/rails/commands/console.rb:45:in `start' 
    from /Users/jasonkim/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.1.3/lib/rails/commands/console.rb:8:in `start' 
    from /Users/jasonkim/.rvm/gems/ruby-1.9.3-p0/gems/railties-3.1.3/lib/rails/commands.rb:40:in `<top (required)>' 
    from script/rails:6:in `require' 
    from script/rails:6:in `<main>' 

Coverage.new работает только отлично, кстати.

Кроме того, когда я настраиваю route.rb и создаю адрес, который запускает метод grab, он отлично работает.

Я угадываю, что когда я запускаю Coverage.grab, где нет какого-либо экземпляра Coverage, я должен запустить метод «grab».

Любая идея, как я могу исправить эту проблему?

ответ

3

Сначала вы определяете метод в CoverageController, а не на Coverage Во-вторых, можно определить метод экземпляра, который, таким образом, действует только на экземпляре класса. Вы можете назвать это так:

coverages_controller = CoveragesController.new 
coverages_controller.grab 
+0

Thanks Holger Просто и все остальные.Хотя Иордания и Клиф верны в своих ответах, в контексте Rails, то, что предложил Хольгер, кажется, лучше всего работает. –

+1

Контроллеры Rails не предназначены для создания экземпляров, кроме как с помощью фреймворка, и это плохое решение imho. Если вы хотите, чтобы метод grab в контроллерах мог перенести его на ApplicationController максимум (и называть его через наследование), но лучше всего поместить его в свой собственный класс RemoteRequest или аналогичный, скорее всего, метод класса. – clyfe

+1

@clyfe Как правило, вы правы. Контроллеры Rails лучше всего использовать только для маршрутизатора Rails. Но из правила всегда есть исключения. Например. когда вы используете сервисные слои (и не воспринимаете слой с именем очень серьезным), тогда может возникнуть смысл напрямую создавать экземпляр и вызывать метод контроллера. Хотя вы должны убедиться, что не используете информацию об окружающей среде, такую ​​как хэш или сеансы params. Так что да, большую часть времени более разумно создавать сервисные слои или моделировать абстракции за пределами обычного ActiveRecord/ActionPack. –

3

Coverage и CoverageController не то же самое. Вы определили grab как метод экземпляра класса CoverageController, но вы пытаетесь вызвать Coverage.grab, метод класса в классе Coverage.

Если вы хотите быть в состоянии назвать Coverage.grab вы определили бы это так:

class Coverage < ActiveRecord::Base 
    def self.grab 
    puts "foo" 
    end 
end 

# Usage 
>> Coverage.grab 
=> foo 

Если вы хотите grab быть действия в CoverageController, однако, вы определили его правильно. Но это метод экземпляра, а не метод класса - вы не можете вызвать CoverageController.grab, потому что CoverageController - это сам класс, а не экземпляр класса, и нет метода класса grab.

Как правило, вы не будете вызывать методы непосредственно на контроллерах - вы оставляете это до маршрутизатора. Вы могли бы попытаться создать экземпляр экземпляр CoverageController, например .:

>> @cc = CoverageController.new ... 
>> @cc.grab 

Но это будет ошибкой, если не обеспечить такую ​​же среду и параметры маршрутизатора будет.

2

Вы определили метод grab как метод экземпляра на CoveragesController, а затем попытались вызвать его как метод класса в классе Coverages.

Что вам нужно сделать, это определить его как метод класса класса Coverages.

class Coverages 
    def self.grab 
    # ... 
    end 
end 
Смежные вопросы