redirect_to和render是可交换的吗?

对于下面的代码,如果用render或vise versereplaceredirect_to会发生什么?

def create @product = Product.new(params[:product]) respond_to do |format| if @product.save format.html { redirect_to(@product, :notice => 'Product was successfully created.') } else format.html { render :action => "new" } end end end 

在上面的代码中,好像用另一个代替另一个。 有没有一个地方只有redirect_to或渲染必须使用? 渲染只会渲染视图。 Redirect_to向服务器发送302请求,redirect后当前参数丢失。

谢谢。

如果您使用render ,当用户刷新页面时,它将再次提交以前的POST请求。 这可能会导致不必要的结果,如重复购买等。

在这里输入图像说明

但是,如果您使用的是redirect_to ,当用户刷新页面时,它只会再次请求相同的页面。 这也被称为Post / Redirect / Get(PRG)模式。

在这里输入图像说明

所以redirect_to应该被使用的地方是当你正在做一个HTTP POST请求,并且你不希望用户在完成时重新提交请求(这可能会导致重复的项目和其他问题)。

在Rails中,当模型未能被保存时, render被用来重新显示以前填充的相同条目的表单。 这很简单,因为如果使用redirect,则必须使用参数或会话传递表单条目。 副作用是,如果刷新浏览器,它将尝试重新提交以前的表单条目。 这是可以接受的,因为它可能会以同样的方式失败,或者如果它现在成功了,无论如何,这是用户应该期望的。

关于renderredirect更深入的解释,你应该阅读这篇文章 。

当你redirect你将产生一个新的请求,命中一个控制器方法,渲染只呈现相关的视图。 在创build中使用了渲染,因为如果保存失败,您希望保留模型对象的状态,以便渲染有关其错误的信息。 如果您尝试redirect到new_productpath,您将创build一个新的模型对象,并释放用户input的所有表单数据以及任何错误等

编辑(与一些更多的信息):

您必须使用redirect_to的情况的一个例子是,如果您的视图模板使用实例variables,而这些variables未在您redirect的控制器方法中初始化。 所以你可能不能在你的create方法中调用render {:action => 'index'} ,因为索引模板可能会使用@productsvariables,但是只能初始化@product所以会引发exception