当我查看 Rails 控制器的示例时,我通常会看到如下内容:
class WidgetController < ActionController::Base
def new
@widget = Widget.new
end
def create
@widget = Widget.new(params[:id])
if @widget.save
redirect_to @widget
else
render 'new'
end
end
end
这可行,但有几个问题:
路线
如果我将小部件添加到我的 routes.rb 文件中:
Example::Application.routes.draw do
resources :widgets
end
GET /widgets/new
will route tonew
和POST /widgets
will route to create
。
如果用户在新的小部件页面上输入错误信息并提交,他们的浏览器将显示带有 的 URL /widgets
,但会呈现新模板。如果用户为页面添加书签并稍后返回或刷新页面,则将调用索引操作而不是新操作,这不是用户所期望的。如果没有索引操作或用户无权查看它,则响应将是 404。
代码重复
作为一个人为的例子,假设我的新方法中有一些棘手的逻辑:
def new
@widget = Widget.new
do_something_tricky()
end
使用当前的方法,我会在new
and中复制该逻辑create
。我可以调用new
from create
,但是我必须修改new
以检查是否@widget
已定义:
def new
@widget ||= Widget.new
do_something_tricky()
end
另外,这感觉不对,因为它降低了控制器操作的正交性。
该怎么办?
那么解决这个问题的Rails 方法是什么?我应该重定向到new
而不是呈现新模板吗?我应该打电话new
到里面create
吗?我应该忍受它吗?有没有更好的办法?