未使用重定向设置实例变量

Instance variable not set with redirect

什么会导致我的实例变量@product 不是set/passed 用于重定向。 Product 是一个 ActiveModel 对象,而不是 ActiveRecord。更具体地说,@product 变量没有出现在 redirect_to(new_services_path) 或 redirect_to(home_path) 页面中。由于@product 变量需要在我的每页页脚中填充一个表单。

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

与原版相关的问题 post..

实例变量不通过重定向传递。

因此,您在到达 before_filter 时没有 @product 对象,因此您每次都只是创建新的空 Product 对象。

ActiveModel 对象无法在会话之间持续存在,但您可以将属性保留在会话存储中并在 before_filter

中使用它
def set_product
  @product = Product.new(session[:product]) if session[:product]
  @product ||= Product.new
end

然后在您的创建方法中将表单参数移至会话...

def create
  session[:product] = params[:product]
  set_product 
  if @product.category == 'wheels'
  ---

请注意,我们在创建方法中显式调用了 set_product,因为会话[:product] 已重新建立。

如果您想知道为什么实例变量会丢失...在创建方法中,您处于 ProductController 的实例中,并且该实例具有自己的实例变量。当您重定向时,您是在指示 rails 创建其他(或相同)控制器的新实例,而那个全新的控制器对象,它没有建立实例变量。

要添加到 SteveTurczyn 的答案,您需要阅读有关 object orientated programming 的内容。在我这样做之后,所有 @instance 变量的东西变得 lot 更清晰。

Very good write-up


Ruby是面向对象的,意味着每次发送请求,它都必须调用所有相关的对象 (类) 供您互动:

此请求的持续时间称为实例。重定向调用 new 请求;因此,您的各种 类.

的新 实例

这就是每次用户与新操作交互时必须调用新 @instance 变量的原因:

#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

--

因此,当你问...

@product variable need to populate a form in my footer that is on every page.

您需要记住,这将在您的操作呈现时每次 被调用。你已经这样做了;问题是您没有保留数据:

#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 在他提到将数据放入会话时得到它。根据 docs...

HTTP is a stateless protocol. Sessions make it stateful.

Steve 提到的解决方案适用于较小的数据量,但如何获取一些记录并使用 redirect_to 传递它呢?会话不允许我们那么多space.

我所做的是将这些记录设置在一个 flash 对象中,当它重定向到页面时,flash 成功地为我呈现了数据。

flash[:products] = @products
redirect_to users_path

让我知道它是如何工作的...