2011-02-18 82 views
9

我是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之後顯示,但感覺像是一個黑客。這似乎應該有一個「軌道」來做到這一點。

想法?

+0

我對Rails核心的投訴完全一樣,但你比我更好地表達了它:)好問題。 – Andrew 2011-04-03 03:35:09

回答

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提交表單),

  1. /things/new的網址更改爲/things
  2. 點擊回提示重新提交表格後
  3. 刷新顯示things#index

這是而不是我在自己的Rails 3應用程序中遇到的功能。相反,我發現:提交新thing(在/things/new提交表單),

  1. /things/new的網址更改爲/things(這是相同的)
  2. 點擊回將用戶回後非 -submitted形式(重後不請求)
  3. 刷新提示重新提交表單(如預期在我看來)
+1

謝謝布蘭登。這很有幫助,但我仍然不在乎默認功能。我想我只會使用JavaScript驗證,以儘可能避免它。 – dearlbry 2011-02-21 16:38:06

0

我知道這是一個老問題,但最近我一直在玩的一種方法是使用AJAX提交表單,即使它不需要它。這可以讓您將其提交到默認的創建/更新操作,只要路由通過,但瀏覽器中的URL不會更改。通過指向/ index頁面的鏈接或者在成功保存時重定向到的位置,或者數據無效時出現錯誤消息的「400錯誤請求」,響應可以是成功的簡單200。

最大的缺點是錯誤消息和無效字段的顯示現在完全是您的客戶端JavaScript的責任。這變成了一個小得多的問題,一旦你在客戶端使用了Backbone或KnockoutJS之類的東西,它甚至會成爲一件好事。

相關問題