rails:如何访问应用程序控制器中的方法?

时间:2010-12-07 20:49:47

标签: ruby-on-rails

Noob范围问题,我想。 :\

class ApplicationController < ActionController::Base
  protect_from_forgery

  @locations = get_locations

  def get_locations
    Location.where(:active => true).order('name').all
  end

end

错误:

undefined local variable or method `get_locations' for ApplicationController:Class

两个问题: 1)错误是什么?我是否错误地调用了该方法? 2)如何从子类控制器访问此方法?

4 个答案:

答案 0 :(得分:9)

您在类范围内调用get_locations,但该方法是实例方法,而不是类方法。例如,如果您使用def self.get_locations,那么您将提供一个类方法,其中一个可以在类范围内使用(在您定义之后,而不是像您之前那样)。

这里的问题是逻辑,这个方法是什么?你打算用@locations做什么?如果要进入应用程序视图,那么您应该将此方法放入ApplicationHelper模块,并从相关操作内部调用它。如果你想在另一个控制器的另一个视图中使用它,并且想在@locations方法中使用locations,那么您的设置可能如下所示:

<强> PagesController

class PagesController < ActionController::Base
  def locations
    @locations = Location.where(:active => true).order('name').all
  end
end

<强> locations.html.erb

<% @locations.each do |location| %>
  <%= # do something with 'location' %>
<% end %>

如果您想在application.html.erb内使用此功能,可以将其简化为一些......

<强>的ApplicationController

class ApplicationController < ActionController::Base
  protect_from_forgery

  def locations
    Location.where(:active => true).order('name').all
  end
 end

<强> application.html.erb

<% locations.each do |location| %>
  <%= # do something with location %>
<% end %>

答案归结为逻辑,要真正弄清楚你在寻找什么,可能需要更多细节。

答案 1 :(得分:3)

您是从类范围调用它,而不是从实例范围调用它。您想要的更多可能是以下内容:

class ApplicationController < ActionController::Base
  protect_from_forgery
  before_filter :setup_locations


  private
  def setup_locations
    @locations = Location.where(:active => true).order('name').all
  end

end

要使原始示例有效,您需要在self上定义#get_locations(在定义时指向类),如下所示:

class ApplicationController < ActionController::Base
  protect_from_forgery

  @locations = get_locations

  def self.get_locations
    Location.where(:active => true).order('name').all
  end

end

该代码的问题在于@locations只能从类级别作为类实例变量使用,这与大多数其他语言中的静态变量相当,而且可能不是您想要的。

答案 2 :(得分:1)

我想这一行:

@locations = get_locations

...正在尝试访问类级别方法get_locations而不是实例方法。

这里的线索是错误消息显示它无法在本身(ApplicationController:Class)上找到它,而不是该类的实例。这意味着您处于类范围内,而不是实例范围。

这会解决它:

  def self.get_locations
     Location.where(:active => true).order('name').all
  end

答案 3 :(得分:1)

即使问题很老,您也可以通过调用以下方式在任何地方调用控制器操作:

ApplicationController.new.get_locations