何时使用实例变量进行渲染,何时进行重定向?

时间:2013-09-01 04:11:26

标签: ruby-on-rails controller

我的newedit页面取决于@important_datacreate操作中未使用的update实例变量。

因此,我的页面无法在失败时呈现new页面。

def create
  @my_object = MyObject.new(params[:my_object])
  if @my_object.save
    redirect_to root_path
  else
    render action: "new"
    #this can't render because the page asks for an @important_data variable that's not defined.
  end
end 

我应该选择以下两种解决方案中的哪一种? 各自有哪些优点/缺点?

选项1:在渲染之前声明@important_data

def create
  @my_object = MyObject.new(params[:my_object])
  if @my_object.save
    redirect_to root_path
  else
    @important_data = ImportantData.all
    render action: "new"
  end
end 

选项2:重定向

def create
  @my_object = MyObject.new(params[:my_object])
  if @my_object.save
    redirect_to root_path
  else
    redirect_to new_my_object_path
  end
end 

3 个答案:

答案 0 :(得分:1)

Offcourse,Option1将最有效,因为您只在出现错误时呈现新的。此外,重定向会使用户体验陷入困境,再次使用相同的查询@important_data = ....再次渲染页面需要一段时间。

答案 1 :(得分:1)

当您使用render时,您使用@my_object来更新params[:my_object]的属性。大多数情况下,这就是你想要的。当您向用户显示页面时,您希望保留对表单所做的更改并向其显示错误。

当您使用redirect时,您正在执行不同的额外请求,因此不会保留从表单提交的参数(除非您在调用中将它们传递给重定向并在控制器操作中构建它们)

因此,在大多数情况下,您肯定希望在验证失败时声明@important_data。我想不出你想要重定向的情况。

答案 2 :(得分:1)

我认为你应该使用 OPTION1

  

因此,应该使用redirect_to的地方是您正在执行HTTP POST请求并且您不希望用户在完成请求时重新提交请求(这可能会导致重复项目和其他问题)。

     

在Rails中,当模型无法保存时,渲染用于重新显示具有先前填充的相同条目的表单。这更简单,因为如果使用重定向,则必须使用参数或会话传递表单条目。副作用是,如果刷新浏览器,它将尝试重新提交以前的表单条目。这是可以接受的,因为它可能会以同样的方式失败,或者如果它现在成功,那么无论如何,这都是用户应该期待的。

上述答案可参考:Are redirect_to and render exchangeable?