Search code examples
ruby-on-railsrubyscopeinstance-variables

Why do my controller's instance variables not work in views (Rails)


I would like to add a couple of instance variables to my controller, since the variables in question are required from within more than one action's view. However, the below example does not work as I would expect.

class ExampleController < ApplicationController
  @var1 = "Cheese"
  @var2 = "Tomato"

  def show_pizza_topping
    # What I want is the above instance vars from within the view here
  end

  def show_sandwich_filling
    # What I want is the above instance vars from within the view here
  end
end

As I understand it, Rails takes the instance variables from the controller and makes them available in the view. If I assign the same variables within the action methods, it works fine - but I don't want to do it twice. Why does my way not work?

(Note: this is a bit of a rubbish example, but I hope it makes sense)

EDIT: I have found the answer to this question here: When do Ruby instance variables get set?

EDIT 2: when is the best time to use filters such as before_filter and the initialize method?


Solution

  • These types of things should be handled in a before_filter. A before filter, like the name implies, is a method that will get called before any actions, or only the ones you declare. An example:

    class ExampleController < ApplicationController
    
      before_filter :set_toppings
    
      def show_pizza_topping
        # What I want is the above instance vars from within the view here
      end
    
      def show_sandwich_filling
        # What I want is the above instance vars from within the view here
      end
    
    protected
    
      def set_toppings
        @var1 = "Cheese"
        @var2 = "Tomato"
      end
    
    end
    

    Or, you could have your before_filter only work on one of your actions

    before_filter :set_toppings, :only => [ :show_pizza_topping ]
    

    Hope this helps.

    EDIT: Here's some more information on filters in ActionController.