Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

rails: how do i access a method in my application controller?

Noob scoping issue, I imagine. :\

class ApplicationController < ActionController::Base
  protect_from_forgery

  @locations = get_locations

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

end

Error:

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

Two questions: 1) What's with the error? Am I calling the method incorrectly? 2) How do I access this method from a sub-classed controller?

like image 320
jmccartie Avatar asked Dec 07 '10 20:12

jmccartie


People also ask

What decides which controller receives which requests in Rails?

Routing decides which controller receives which requests. Often, there is more than one route to each controller, and different routes can be served by different actions. Each action's purpose is to collect information to provide it to a view.

What does Before_action do in Rails?

When writing controllers in Ruby on rails, using before_action (used to be called before_filter in earlier versions) is your bread-and-butter for structuring your business logic in a useful way. It's what you want to use to "prepare" the data necessary before the action executes.

How do I use filters in Ruby on Rails?

Rails after filters are executed after the code in action controller is executed. Just like before filters, after filters are also defined at the top of a controller class that calls them. To set it up, you need to call after_filter method.


2 Answers

You're calling get_locations within the class scope, but the method is an instance method, not a class method. If for example you used def self.get_locations then you would be providing a class method, one of which you can use within the class scope (after you have defined it, not before like you're doing).

The problem here is the logic, what is this method for? What do you intend to use @locations for? If it's to go inside your application view, then you should put this method into the ApplicationHelper module, and call it from inside the relevant action. If you'd like it in another view on another controller and you'd like to use @locations inside your locations method, perhaps your setup might look something like this:

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 %>

If you'd like to use this inside of your application.html.erb you can simplify it quite some..

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 %>

The answer boils down to logic, and to really figure out exactly what you're looking for, more details would probably be required.

like image 162
Lee Jarvis Avatar answered Oct 05 '22 06:10

Lee Jarvis


You're calling it from the class scope, not from an instance scope. more likely what you want is the following:

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

To make your original example work, you'd need to make #get_locations defined on self (which points to the class at definition), like so:

class ApplicationController < ActionController::Base
  protect_from_forgery

  @locations = get_locations

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

end

The problem with that code is that @locations will only be available from the class level as a class instance variable, which is comparable to a static variable in most other languages, and which probably isn't what you want.

like image 32
Keith Gaddis Avatar answered Oct 05 '22 06:10

Keith Gaddis