Rail 3:重定向后实例变量不可用

时间:2012-04-11 11:04:05

标签: ruby-on-rails redirect

我在Rails 3中有一个表单向导。基本上,我创建了一个酒店对象,然后当所有这些都完成后,我想为该酒店创建一个位置对象。我创建酒店的控制器代码如下所示:

  def create
    @hotel = Hotel.new(params[:hotel])

    respond_to do |format|
      if @hotel.save
        @location = Location.new
        format.html { redirect_to '/set_location'}
      else
        format.html { render action: "new" }
      end
    end
  end

然后在'/ set_location'页面中我有一个设置位置的表单。但是,我在@location实例变量的html.erb上收到'undefined method model_name for NilClass:Class'错误。

这真的很奇怪,因为当我使用render'/ set_location'而不是redirect_to时,它工作正常。但是,我想使用redirect_to方法来防止重复记录提交。

提前感谢您提供任何帮助。

3 个答案:

答案 0 :(得分:15)

HTTP在设计上是无状态的。如果要在请求之间共享状态(将引导重定向到另一个请求),则应使用session哈希。像这样:

session[:hotel_id] = @hotel.id

然后您以Hotel的方式检索/set_location

Hotel.find(session[:hotel_id])

答案 1 :(得分:1)

我相信你想要做的是:

  1. 确定哪个控制器和操作响应“/ set_location”请求。
  2. 在那里你会看到你错过了这一行@location = Location.new。你需要在那里创建它。
  3. Rails中的实例变量通常用于在控制器和视图之间传递信息,这就是为什么在执行渲染时,您不会收到该错误。 Rails视图了解控制器的实例变量。

    但是,您正在进行重定向,因此您正在调用另一个不知道@location是什么的控制器。

答案 2 :(得分:0)

我相信Nobita在这里的回答是最全面的,并且回答了OP的确切问题。请投票(@Ger)。

在jdoe的回答中,我期待或希望看到更多关于他/她(jdoe' s)使用"请求"的解释。在他的解释中,作为"请求"可以解释为对其他框架中的视图(或模板)的请求,因此当使用Rails读取时,此语句可能对新Rails开发人员(包括我自己)有点误导:

  

"变量不能在请求之间传递。我觉得作者得到了   想法:使用会话。"

从某种意义上说,当您使用" render"从控制器请求视图/模板时,确实可以传递变量。因此,如果您的控制器方法呈现视图,则该视图将了解您在该控制器中定义的@variable

此外,使用会话实际上不是在请求之间传递变量的唯一方法。您可以修改重定向到路由以捕获变量:

考虑(在routes.rb文件中):

match 'surveys/result(/:id)' => "surveys#result", via: [:get], as: 'surveys_result'

现在,在"调查"控制器"结果"动作方法您将拥有:id参数。您可以将其称为params[:id],例如,使用此ID在数据库中查找对象。我相信,还有一种方法可以隐藏URI / URL中的:id,以防您不希望用户在那里看到它。

@shime:关于"重复条目"的问题,我认为OP指的是在POST请求上呈现视图。想象一下,如果POST成功,那么在您已经提交该表单之后,您可能会在每次刷新页面时向数据库提交一个重复的条目(重定向方法会处理这种情况不会发生,因此是标准方式)从您的POST请求路由)和我发现的这个段落对两个实现中发生的事情有一个最明确的解释:

https://gist.github.com/jcasimir/1210155#redirect