我是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),用户以前的提交将丢失,错误消息也将丢失。
我意识到RESTful,这个方法可能是“正确的”,因为事物对象的创建应该是POST到/ thing的结果,但是用户界面方面,我并不特别关心它。
我可以“手动”将无效的@thing对象保存在用户的会话中,在我将其重定向回new_thing_path之后显示,但这感觉就像是黑客。似乎应该有一种“轨道方式”来做到这一点。
想法?
答案 0 :(得分:3)
正如您所发现的,默认情况下,当您指定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
(这是相同的)答案 1 :(得分:0)
我知道这是一个老问题,但我最近一直在玩的一种方法是用AJAX提交表单,即使它不需要它。这使您可以将其提交到路由的默认创建/更新操作,但浏览器中的URL不会更改。响应可以是一个简单的200成功,带有指向/索引页面的链接或成功保存时重定向到的位置,或者如果数据无效则带有错误消息的“400错误请求”。
最大的缺点是错误消息和无效字段的显示现在完全由您的客户端javascript负责。这成为一个小得多的问题,一旦你在客户端使用Backbone或KnockoutJS之类的东西,它甚至可能是一件好事。