据我所知,这是用于编辑和更新资源的标准 rails 模式。
我有一个用于编辑操作的 GET 路由/users/:id/edit
和一个用于更新操作的 PUT 和 PATCH 路由/users/:id
。
这是我的控制器操作:
def edit
@user = User.find params[:id]
end
def update
@user = User.find params[:id]
if @user.update_attributes(user_params)
redirect_to @user, success: "Changes saved"
else
flash.now.alert = "Unable to change account details"
render :edit
end
end
我在我的表单部分中使用了默认的 form_for:
<%= form_for @user do |f| %>
在 html 中创建以下表单:
<form accept-charset="UTF-8" action="/users/1" id="edit_user_1" method="post">
...
<input name="_method" type="hidden" value="patch">
当调用update_attributes
成功时,用户被正确重定向,但是当调用失败时(由于 ActiveRecord 验证),渲染操作正确显示编辑视图,但用户浏览器中的路径从 更改/users/1/edit
为/users/1
。
根据我的阅读,这似乎是 rails 的预期行为,但这让我感到困惑,因为我认为 REST 背后的核心思想是 URL 引用资源的规范视图?
如果我redirect_to
使用编辑操作而不是render
URL 应该是这样,但是我会丢失表单上的错误消息。
有没有比在使用 redirect_to 之前将错误转储到会话中更明智的方法来保存 URL 和错误消息?如果可以的话,我想避免这种情况。
更新:
我希望 URL 持续存在(以及错误)的原因是因为我正在使用 current_page? 在导航中设置活动状态。因此,如果表单提交错误,菜单中的“编辑”操作将失去突出显示。