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

我在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’页面中,我有一个设置位置的表单。 但是,我在html.erb上为@location实例变量获取了一个'undefined method model_name for NilClass:Class'错误。

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

在此先感谢任何帮助。

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

 session[:hotel_id] = @hotel.id 

然后以这种方式检索/set_location Hotel

 Hotel.find(session[:hotel_id]) 

我相信你想要做的是:

  1. 确定哪个控制器和操作响应“/ set_location”请求。
  2. 在那里你会看到你错过了这行@location = Location.new 。 你需要在那里创建它。

Rails中的实例变量通常用于在控制器和视图之间传递信息,这就是为什么在执行渲染时 ,您不会收到该错误。 Rails视图了解控制器的实例变量。

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

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

在jdoe的回答中,我期待或希望在他的解释中看到关于他/她(jdoe)使用“请求”的更多解释,因为“请求”可以被解释为对其他框架中的视图(或模板)的请求,所以当使用Rails读取时,这个语句可能会对新的Rails开发人员(包括我自己)产生误导:

“变量不能在请求之间传递。我认为作者有这样的想法:使用会话。”

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

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

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

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

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

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

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