What would cause my instance variable @product to not be set/passed for the redirect. Product is an ActiveModel object, not ActiveRecord. to be more specific, the @product variable is not appearing in the redirect_to(new_services_path) or redirect_to(home_path) pages. As the @product variable need to populate a form in my footer that is on every page.
Application_controller:
class ApplicationController < ActionController::Base
before_filter :set_product
private
def set_product
@product ||= Product.new
end
end
Product_controller:
def new
end
def create
@product = Product.new(params[:product])
if @product.category == "wheels"
redirect_to(new_services_path)
else
redirect_to(home_path)
end
end
Issue related to this original post.. Passing variables through multiple partials (rails 4)
Instance variables are not passed on a redirect.
Consequently, you have no @product
object at the time you are reaching the before_filter
and so you're just creating the new and empty Product
object each time.
ActiveModel objects can't persist from session to session, but you can keep the attributes in your session store and use that in your before_filter
def set_product
@product = Product.new(session[:product]) if session[:product]
@product ||= Product.new
end
And in your create method you move the form params to the session...
def create
session[:product] = params[:product]
set_product
if @product.category == 'wheels'
---
Notice that we called set_product
explicitly in the create method because the session[:product] had been re-established.
In case you're wondering WHY the instance variable is lost... in the create method you are in an instance of ProductController and that instance has it's own instance variables. When you redirect, you are instructing rails to create a NEW instance of some other (or the same) controller, and that brand new controller object, it has no instance variables established.
To add to SteveTurczyn
's answer, you need to read up about object orientated programming. After I did, all the @instance
variable stuff became a lot clearer.
Very good write-up
Ruby is object-orientated, meaning every time you send a request, it has to invoke all the relative objects (classes) for you to interact with:
The duration of this request is called an instance. Redirecting invokes a new request; hence a new instance of your various classes.
This is why you have to invoke new @instance
variables each time your users interact with a new action:
#app/controllers/your_controller.rb
class YourController < ApplicationController
def edit
@model = Model.find params[:id]
end
def update
@model = Model.find params[:id] #-> new request = new instance
end
end
--
Thus, when you ask...
@product
variable need to populate a form in my footer that is on every page.
You need to remember that this will be invoked every time your actions are rendered. You already do this; the problem is that you're not persisting the data:
#app/controllers/application_controller.rb
class ApplicationController < ActionController::Base
before_filter :set_product
private
def set_product
@product ||= Product.new #-> after "create", params[:product] = nil (new instance)
end
end
@SteveTurczyn
got it when he mentioned putting the data into the session. As per the docs...
HTTP is a stateless protocol. Sessions make it stateful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With