当我查看 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/newwill route tonew和POST /widgetswill route to create。
如果用户在新的小部件页面上输入错误信息并提交,他们的浏览器将显示带有 的 URL /widgets,但会呈现新模板。如果用户为页面添加书签并稍后返回或刷新页面,则将调用索引操作而不是新操作,这不是用户所期望的。如果没有索引操作或用户无权查看它,则响应将是 404。
代码重复
作为一个人为的例子,假设我的新方法中有一些棘手的逻辑:
def new
  @widget = Widget.new
  do_something_tricky()
end
使用当前的方法,我会在newand中复制该逻辑create。我可以调用newfrom create,但是我必须修改new以检查是否@widget已定义:
def new
  @widget ||= Widget.new
  do_something_tricky()
end
另外,这感觉不对,因为它降低了控制器操作的正交性。
该怎么办?
那么解决这个问题的Rails 方法是什么?我应该重定向到new而不是呈现新模板吗?我应该打电话new到里面create吗?我应该忍受它吗?有没有更好的办法?