views:

811

answers:

2

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: http://stackoverflow.com/questions/826734/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?

+5  A: 

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.

theIV
Yes it does, thank you. However, shortly after posting this I found another answer (I updated the question to reflect this). When is the best time to use before_filter and/or initialize?
Splash
I would say that you should use a before_filter if it's any sort of set up work that has to work on multiple actions.
theIV
As an example of the comment I just left, when verifying that someone is logged in, you might typically have a method in `ApplicationController` and apply a `before_filter` to any action that requires the user be logged in. It wouldn't make sense having that code in every action that requires someone be logged in.
theIV
Understood - this would make it easier to split up into multiple filter methods if necessary, and/or allocate to specific action(s) if necessary. Thank you - that's a bit of a Ruby gotcha when you come from C-like languages.
Splash
For better organization and readability it's better to use before_filter.
Vizjerai
+2  A: 

Those aren't instance variables, are they?

class A
  @x = 5
  def f
    puts @x
  end
end

A.new.f
=> nil

You're defining it at the class-level, not the instance-level. As "theIV" points out, you need to assign them inside an instance method.

Ken
I was under the mistaken impression you could do it in that way like in languages such as c# or Java:class ExampleController { private string var1 = "cheese"; // ...}
Splash
In Java, there, you're declaring an instance variable; in Ruby, you variables are not declared, so there's no real equivalent. Anything inside the Ruby "class".."end" is basically evaluated, so it might help to think of that as equivalent to a Java static initializer.
Ken