据我所知,这是用于编辑和更新资源的标准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
Run Code Online (Sandbox Code Playgroud)
我在我的表单部分中使用默认的form_for:
<%= form_for @user do |f| %>
Run Code Online (Sandbox Code Playgroud)
这是在html中创建以下表单:
<form accept-charset="UTF-8" action="/users/1" id="edit_user_1" method="post">
...
<input name="_method" type="hidden" value="patch">
Run Code Online (Sandbox Code Playgroud)
当update_attributes正确重定向用户调用时,无论何时调用失败(由于ActiveRecord验证),渲染操作都会正确显示编辑视图,但用户浏览器中的路径将更/users/1/edit改为/users/1.
根据我的阅读,这似乎是rails的预期行为,但这似乎让我感到困惑,因为我认为REST背后的核心思想是URL是指资源的规范视图?
如果我redirect_to对编辑操作而不是render那个url是应该的,但是我丢失了表单上的错误消息.
在使用redirect_to之前,是否有更明智的方法来保留URL和错误消息,而不是将错误转储到会话中?如果可以,我想避免这样做.
更新:
我希望URL保持(以及错误)的原因是因为我正在使用current_page?在导航中设置活动状态.因此,如果表单提交错误,菜单中的"编辑"操作将失去突出显示.
您所在的原因/users/1是该视图是由 呈现的#update,而不是#edit。
默认资源的路径#update与 相同,但#show请求方式不同。因此,当渲染 HTML 响应时,它与.GETPUT#update#show
我认为结果是可以接受的,无论你走哪条路,结果都是预期的。正如您已经发现的,如果使用redirect,@user实例将更改为新分支,从而丢失错误和之前的填充。
路径上有解决方法,例如使用会话传递实例变量,但我认为这不值得付出努力。目前的结果已经足够好了。
操纵活动状态很容易。我不喜欢current_page?需要太多代码。使用controller_pathandaction_name代替。
if controller_path == 'users' && (action_name == 'edit' || 'update')
# add active class
end
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1579 次 |
| 最近记录: |