Understanding Rails Instance Variables
Instance variables are in the instance class scope. In Ruby on Rails, because the way how that API was built, instance variables are also available in the views.
You need to be aware of that new and create methods are commonly used in different ProductsController
instances.
First request: GET http://localhost:3000/product/new
When you ask for the new
action (I suppose that is a form), Rails API implementation at a given point creates an instance of ProductsController
and sends the new
message to that instance (calls the new method). Then, the instance variable @product is created and available in any method, or in any view that the action renders. At a given point, Rails replies with a web page and the class instance, and all its instance variables, are destroyed (won't be available anymore).
Second request: POST http://localhost:3000/product/create
When you submit the form for database persistence, again a new controller instance is created, and the create
method is called. Because is a new instance, the @product doesn't have any value.
Note, however, that there is a difference between rendering a view (like its happening in the new
action) and a redirect (like you do in the create
action if @product.save
is true). When you render, you remain in the same controller instance, with you redirect, new server request happens, so the previous controller instance is destroyed and a new controller instance is created.
The before action
before_action is called before you actually start executing the action code. In Rails perspective, an action is not a Ruby method. The class method is the definition of that action:
From Rails guides:
A controller is a Ruby class which inherits from ApplicationController
and has methods just like any other class. When your application
receives a request, the routing will determine which controller and
action to run, then Rails creates an instance of that controller and
runs the method with the same name as the action.
The action acts as an entry point determined by the routes. If you call create inside new, it won't trigger that before_action again.
What is the scope of an instance variable in a Rails controller?
An instance variable in a Rails controller is used in two ways:
- It is available within instance methods of that controller (including superclass instance methods), just like any other Ruby instance variable.
When a Rails controller action renders a view, the controller's instance variables are copied (shallowly) to the view instance. (The view instance is the value of
self
within a template.) Controller instance variables defined at the time an action renders are therefore effectively available within that action's view. View helpers are just modules which are extended by the view instance, so controller instance variables are effectively available within view helper methods too.Note that although controller instance variables are copied to the view, instance variables defined in the view are not copied back to the controller. That's not something you'd normally need to have happen because rendering the view is normally the last thing done in a controller action. And local variables defined in a view are available throughout the view, so there's no reason at all to define an instance variable in a view.
An instance variable in a given controller is not available within other controllers, within other controllers' views, or within any models at all.
Defining instance variables in rails controllers
In this case, defining instance variable in users#new
, for example, is necessary for it to be accessible in view. Rails uses this specific mechanism to copy all the instance variables defined in controller context to view.
On the other hand, in sessions#create
you only want to redirect the user if sign in is successful and display sign in form otherwise, which - as you see in sessions#new
- doesn't require any instance variables defined. So local variable in this case is sufficient.
Lifecycle of Instance variables in Ruby on Rails
Rails controller is instantiated per request. It means that every time you receive a request all instance variables are nil
and you need to initialize them.
Ruby on Rails, Instance variables is persisting through multiple requests
What Alex said in the comments is correct:
The current_transaction_batch_id
method is a class method. By setting the instance_variable @current_transaction_batch_id
within it, you are setting it on the class, not the instance of the class. By memoizing it you are keeping it unchanged. The class is only loaded once and kept between requests, therefore the value never changes.
You'll need to change your code, so you are working on the instance, not the class:
def current_transaction_batch_id
@current_transaction_batch_id ||= SecureRandom.hex
end
How are parameters sent when I use instance variables in form_for in rails
The form_for
helper creates a form from a model object. If you've set up your Rails app in the conventional way, you will have (it appears) a file called app/models/missed_call_flow.rb
that begins by defining class MissedCallFlow
.
This file defines the model. It is the source of the params[:missed_call_flow]
name, because it is the convention in Rails to name this data structure for the model.
As a generalization in programming, the variable name should not impact the functioning of the program. The fact that you have named your variable @flow
is ignored by the inner workings of your program. It is a convenience to the programmer to be able to name your variable whatever you want.
I wonder if you are not seeing the model name you expect because missed_call_flow
represents a join table between two other tables with models named missed_call
and flow
. You might be assigning an instance of this MissedCallFlow class to the variable @flow
by mistake.
Related Topics
What Are the Limitations of Opal
How to Set a Request.Referrer Inside My Rspec
How to Set the Httponly Flag on a Cookie in Ruby on Rails
How to Use the Ruby "Self" Keyword
Bash: /Home/Xxx/.Rvm/Scripts/Rvm: No Such File or Directory
Wicked-Pdf Not Showing Images, 'Wicked_Pdf_Image_Tag' Undefined
Ruby Gems in Stand-Alone Ruby Scripts
Ruby on Rails User Registration Using Rest API Call and Devise
Rails 4 Update Nested Attributes
Ruby Operator Overloading Question
Ruby - How to Write a New File with Output from Script
Mail Gem - How to Clean Up the Body String
How to Push Keys and Values into an Empty Hash W/ Ruby
Sequel Accessing Many_To_Many Join Table When Adding Association
Ruby Rest-Client File Upload as Multipart Form Data with Basic Authenticaion
Attempting to Install Libv8, "Failed to Build Gem Native Extension"
In Ruby What's the Difference Between Self.Method and a Method Within Class << Self