There is a situation where I need to call my update
action from my create
action:
在某种情况下,我需要从我的创建操作中调用我的更新操作:
def create
@product = Product.find_or_initialize_by_sku(params[:sku])
if @product.new_record?
respond_to do |format|
if @product.save
format.html { redirect_to @product, notice: 'Product was successfully created.' }
format.json { render json: @product, status: :created, location: @product }
else
format.html { render action: "new" }
format.json { render json: @product.errors, status: :unprocessable_entity }
end
end
else
update ##*** I am calling the update action at this point ***##
end
end
def update
@product = Product.find_or_initialize_by_sku(params[:sku])
respond_to do |format|
if @product.update_attributes(params[:product])
format.html { redirect_to @product, notice: 'Product was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @product.errors, status: :unprocessable_entity }
end
end
end
But I end up making two identical queries to my database because I am not sure of the most effective way to pass a variable (in this case, the instance variable @product
) from one action to another.
但我最终对我的数据库进行了两次相同的查询,因为我不确定将变量(在本例中为实例变量@product)从一个动作传递到另一个动作的最有效方法。
I am trying to get a grasp on the 'rails' way to do this. What should I do here (as I know I should not be making two identical database queries)?
我试图抓住'rails'的方式来做到这一点。我该怎么做(据我所知,我不应该做两个相同的数据库查询)?
Would I store it in the session as if I was performing a redirect (Am I performing a redirect when I call an action from within another action like this?)?
我是否会将它存储在会话中,就好像我正在执行重定向一样(当我从另一个动作中调用动作时我是否执行重定向?)?
session[:product] = @product # in my create action
# then
@product = session[:product] # in my update action
Does caching make this all a moot point?
缓存是否使这一切都没有实际意义?
1 个解决方案
#1
3
Consider using memoization:
考虑使用memoization:
@product ||= Product.find_or_initialize_by_sku(params[:sku])
The ||=
operator will check if @product
is nil, and if it is, Ruby will execute the finder. Otherwise, Ruby will use the current value. Therefore, when you call update
from create
, the update
method will use the @product
that you found or initialized in create
.
|| =运算符将检查@product是否为nil,如果是,则Ruby将执行查找程序。否则,Ruby将使用当前值。因此,当您从create调用update时,update方法将使用您在create中找到或初始化的@product。
Regarding your second question, you're not performing a redirect when you call one controller action from another. Try not to over-think it - a controller is just another Ruby class with its own instance variables (e.g. @product
) and methods. To perform a redirect, you would have to call redirect_to
, which would result in a second web request to your controller.
关于第二个问题,当您从另一个调用一个控制器操作时,您没有执行重定向。尽量不要过度思考 - 控制器只是另一个具有自己的实例变量(例如@product)和方法的Ruby类。要执行重定向,您必须调用redirect_to,这将导致向控制器发送第二个Web请求。
#1
3
Consider using memoization:
考虑使用memoization:
@product ||= Product.find_or_initialize_by_sku(params[:sku])
The ||=
operator will check if @product
is nil, and if it is, Ruby will execute the finder. Otherwise, Ruby will use the current value. Therefore, when you call update
from create
, the update
method will use the @product
that you found or initialized in create
.
|| =运算符将检查@product是否为nil,如果是,则Ruby将执行查找程序。否则,Ruby将使用当前值。因此,当您从create调用update时,update方法将使用您在create中找到或初始化的@product。
Regarding your second question, you're not performing a redirect when you call one controller action from another. Try not to over-think it - a controller is just another Ruby class with its own instance variables (e.g. @product
) and methods. To perform a redirect, you would have to call redirect_to
, which would result in a second web request to your controller.
关于第二个问题,当您从另一个调用一个控制器操作时,您没有执行重定向。尽量不要过度思考 - 控制器只是另一个具有自己的实例变量(例如@product)和方法的Ruby类。要执行重定向,您必须调用redirect_to,这将导致向控制器发送第二个Web请求。