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
Suppressing the Output of a Command Run Using 'System' Method While Running It in a Ruby Script
Rails I18N via Database Column
How to Validate a Non-Model Form in Rails 3
Is There a Literal Notation for an Array of Symbols
How to Write a Shell Script That Starts Tmux Session, and Then Runs a Ruby Script
How to Include Video in Jekyll Markdown Blog
How to Convert a String to a Class Method
How to Filter Parameters in Rails
Is Inject the Same Thing as Reduce in Ruby
Making Multiple Http Requests Asynchronously
Options for Distribution of an Offline Ruby on Rails Application
Is There a Simple Way to Get Image Dimensions in Ruby
Printing an Ascii Spinning "Cursor" in the Console
How to Test If a Div Has a Certain CSS Style in Rspec/Capybara