2010-12-07 85 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 
相關問題