Same Instance Variable for All Actions of a Controller

Same instance variable for all actions of a controller

Unless you're rendering show.html.erb from the index action, you'll need to set @some_instance_variable in the show action as well. When a controller action is invoked, it calls the matching method -- so the contents of your index method will not be called when using the show action.

If you need @some_instance_variable set to the same thing in both the index and show actions, the correct way would be to define another method, called by both index and show, that sets the instance variable.

def index
set_up_instance_variable
end

def show
set_up_instance_variable
end

private

def set_up_instance_variable
@some_instance_variable = foo
end

Making the set_up_instance_variable method private prevents it from being called as a controller action if you have wildcard routes (i.e., match ':controller(/:action(/:id(.:format)))')

Ruby on Rails Controller Instance Variable not shared

@cart is an instance variable and it is not persisted between requests. And session is accessible between requests.

Basically if you have set some data into session then you can use that data between requests. As it was mentioned you can setup a before_filter and preset @cart instance variable before executing the update action.

class MyController < ApplicationController
before_action :instantiate_cart, only: [:update] #is the list of actions you want to affect with this `before_action` method
...
private

def instantiate_cart
@cart = Cart.new(session[:cart])
end
end

Rails: Set a common or global instance variable across several controller actions

Firstly, you don't want to try to insert code "between" a controller action and a template rendering. Why? Because you want the controller action to have the freedom to choose what sort of response to give. It could return XML, JSON, headers only, a redirection, nothing, etc. That's why after filters are executed after the response has been rendered.

Secondly, you don't want to monkey patch Fixnum. I mean, maybe you do, but I don't. Not often at least, and not unless I get some totally wicked semantic benefits from it, like being able to say 3.blind_mice. Monkey patching it for a random use case like this seems like a maintenance headache down the road.

You mention refactoring out all the controllers' case specific code into a before filter and running them sequentially. Which brings up to my mind... @foo is the same in every case? If that's the case, then one before filter would work just fine:

before_filter :do_common_stuff
def do_common_stuff
@foo = common_foo
@bar = do_something_with @foo
end

That's a totally legit approach. But if @foo changes from controller to controller... well, you have a few more options.

You can separate your before filters into two halves, and customize one per controller.

# application_controller:
before_filter :get_foo, :do_something_common
def do_something_common
@bar = do_something_with @foo
end

# baz_controller:
def get_foo
@foo = pull_from_mouth
end

#baf_controller:
def get_foo
@foo = pull_from_ear
end

But you know, if it's a simple case that doesn't need database access or network access or anything like that... which your case doesn't... don't kill yourself. And don't sweat it. Throw it in a helper. That's what they're there for, to help. You're basically just rearranging some view data into a form slightly easier to use anyway. A helper is my vote. And you can just name it next_url. :)

Pass instance variable between controllers using a helper

I found a way of making the contact_id accesible to the EngagementsController without having to pass variables from ContactsController to EngagementsController via a helper. The nested resources:

  resources :contacts do
resources :engagements
end

generates the path:

POST   /contacts/:contact_id/engagements(.:format)  engagements#create

Thus the contact_id of the engagement is made accessible to the EngagementsController:

def create
@contact = Contact.find(params[:contact_id])
@engagement = @contact.engagements.build(engagement_params)
end

Instance variable in controllers

The instance variables are available only during the request (controller and view rendering), because Rails create a new instance of controller for each request.

If you want to keep data between request, use sessions.



Related Topics



Leave a reply



Submit