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)如何从子类控制器访问此方法?
答案 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