2010-12-07 52 views
9

Noob范围问题,我想象。 :\rails:我如何访问我的应用程序控制器中的方法?

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)如何从分级控制器访问此方法?

回答

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 

位置.html.erb

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

如果你想使用这个里面你application.html.erb可以对mplify它相当一些..

的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

我想这条线:

@locations = get_locations 

...试图访问类级别方法get_locations,而不是实例方法。

此处的线索是错误消息显示它无法在本身(ApplicationController:Class)上找到它,而不是该类的实例。这意味着你在类作用域中,而不是实例作用域。

这将解决这个问题:

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

@@位置几乎可以肯定不是你想要的。它是一个真正的类变量,它在Ruby中是在类的所有实例之间共享的,*包括子类*,并且可能会有一些非常奇怪的后果。 – karmajunkie 2010-12-07 21:01:03

+0

Woops,注意到(和编辑)。谢谢。 – markquezada 2010-12-07 21:06:34

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 

为了让您的原来的例子工作,你需要做自我(指向在定义类)中定义#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只能从类级别作为类实例变量使用,这与大多数其他语言中的静态变量相当,并且可能不是您想要的。

+0

奇怪的是,第二个例子产生了完全相同的错误。第一个例子似乎工作正常 - 但这会限制我从另一个控制器调用此方法的能力,对吧? (感谢您的帮助!) – jmccartie 2010-12-07 21:05:00

1

即使这个问题是很老,你可以在任何地方也只是通过调用打电话给你的控制器动作:

ApplicationController.new.get_locations 
相关问题