在Rails中处理无效表单提交的正确方法
我是rails新手,我不确定我是否同意我在某些教程中完成的工作。这个问题与如何处理无效表单提交有关。做事的标准方法似乎是:在Rails中处理无效表单提交的正确方法
class ThingsController < ApplicationController
# POST /things
def create
@thing = Thing.new(params[:thing])
if @thing.save
flash[:notice] = 'Thing created'
redirect_to(@thing)
else
render :action => :new
end
end
当@ thing.save失败,用户呈现相同的形式,预填出与他刚输入的值,随着什么地方闪光错误。到目前为止,除了现在URL已经从/ things/new变成了things /之外,其他人都期望渲染索引视图。
此外,如果用户刷新页面,他现在正在查看索引视图。如果他点击回来,他会被提示重新提交表格,这是我一直试图避免的。如果我redirect_to(new_thing_path),用户以前的提交将丢失,错误消息也会丢失。
我意识到RESTfully,这个方法可能是“正确的”,因为事物对象的创建应该是POST/to事件的结果,但用户界面明智的,我并不特别关心它。
我可以“手动”将无效的@thing对象保存在用户的会话中,以便在将他重定向回new_thing_path之后显示,但感觉像是一个黑客。这似乎应该有一个“轨道”来做到这一点。
想法?
正如您发现的,默认情况下,当您指定resources :things
时,用于创建新事物的POST路径为/things
。下面是输出为rake routes
:
things GET /things(.:format) {:action=>"index", :controller=>"things"}
POST /things(.:format) {:action=>"create", :controller=>"things"}
new_thing GET /things/new(.:format) {:action=>"new", :controller=>"things"}
edit_thing GET /things/:id/edit(.:format) {:action=>"edit", :controller=>"things"}
thing GET /things/:id(.:format) {:action=>"show", :controller=>"things"}
PUT /things/:id(.:format) {:action=>"update", :controller=>"things"}
DELETE /things/:id(.:format) {:action=>"destroy", :controller=>"things"}
这听起来像你想要更多的东西是这样的:
create_things POST /things/new(.:format) {:action=>"create", :controller=>"things"}
things GET /things(.:format) {:action=>"index", :controller=>"things"}
new_thing GET /things/new(.:format) {:action=>"new", :controller=>"things"}
edit_thing GET /things/:id/edit(.:format) {:action=>"edit", :controller=>"things"}
thing GET /things/:id(.:format) {:action=>"show", :controller=>"things"}
PUT /things/:id(.:format) {:action=>"update", :controller=>"things"}
DELETE /things/:id(.:format) {:action=>"destroy", :controller=>"things"}
虽然不建议,你可以得到这个结果与下列路线:
resources :things, :except => [ :create ] do
post "create" => "things#create", :as => :create, :path => 'new', :on => :collection
end
您还需要修改表单以使其POST到正确的路径。
所有这些都说了,你在你的问题中的URL描述听起来不对。你列出以下内容:提交新thing
(在/things/new
提交表单),
- 从
/things/new
的网址更改为/things
- 点击回提示重新提交表格后
- 刷新显示
things#index
这是而不是我在自己的Rails 3应用程序中遇到的功能。相反,我发现:提交新thing
(在/things/new
提交表单),
- 从
/things/new
的网址更改为/things
(这是相同的) - 点击回将用户回后非 -submitted形式(重后不请求)
- 刷新提示重新提交表单(如预期在我看来)
谢谢布兰登。这很有帮助,但我仍然不在乎默认功能。我想我只会使用JavaScript验证,以尽可能避免它。 – dearlbry 2011-02-21 16:38:06
我知道这是一个老问题,但最近我一直在玩的一种方法是使用AJAX提交表单,即使它不需要它。这可以让您将其提交到默认的创建/更新操作,只要路由通过,但浏览器中的URL不会更改。通过指向/ index页面的链接或者在成功保存时重定向到的位置,或者数据无效时出现错误消息的“400错误请求”,响应可以是成功的简单200。
最大的缺点是错误消息和无效字段的显示现在完全是您的客户端JavaScript的责任。这变成了一个小得多的问题,一旦你在客户端使用了Backbone或KnockoutJS之类的东西,它甚至会成为一件好事。
我对Rails核心的投诉完全一样,但你比我更好地表达了它:)好问题。 – Andrew 2011-04-03 03:35:09