如何在Rails控制器中将变量从一个操作传递到另一个操作?

时间:2022-05-31 23:09:23

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请求。