2010-09-03 65 views
6

好的,我想了解用於HTML和XML格式的CREATE和UPDATE方法的最佳實踐。一個控制器的默認代碼是由rails generator生成的,對我來說有點不清楚。RESTful控制器的最佳實踐CREATE和UPDATE方法

有關CREATE方法,給出了良好的保存,發電機說爲 「redirect_to的(@whatever)」 HTML和「渲染:XML => @whatever,:狀態=>:創建:位置= > @ XML「。

給定一個不好保存,發電機說要 「渲染:行動=> '新'」 爲HTML和 「渲染:XML => @ whatever.errors,:狀態=>:unprocessable_entity」 爲XML 。

但是,對於更新方法,給出一個很好的更新,發電機說要 「redirect_to的(@whatever)」 爲HTML和 「頭:OK」 爲XML。

而且,由於錯誤的更新,發電機說要 「渲染:行動=> '編輯'」 爲HTML和 「渲染:XML => @ whatever.errors,:狀態=>:unprocessable_entity」對於XML。

我明白這一點,這對我來說很有意義,而且工作得很好 - 但是,我有兩個問題:

首先,對於一個成功的創建和更新,HTML格式,爲什麼「redirect_to的(@whatever )「而不是」render:action =>'show'「?我理解重定向和渲染之間的區別,只是更加好奇你們傾向於這樣做以及爲什麼。看起來重定向對於瀏覽器來說是不必要的額外旅程。

二,爲什麼 「頭:OK」 在通過XML更新成功,但 「渲染:XML => @whatever,:狀態=>:創建:位置=> @whatever」 在成功通過CREATE XML?這對我來說似乎不一致。看起來像通過XML成功的UPDATE應該和通過XML成功的CREATE相同。看起來你需要新的/更新的對象返回,所以你可以測試它。你們怎麼做,爲什麼?

回答

1

我已經寫了這一點,當山姆Ç回答,但在這裏它是無論如何:-)

在第一部分 - 爲什麼重定向,而不是渲染?我能想到的兩個原因:

1)它是一致的。如果您呈現show動作並且用戶稍後使用後退按鈕返回到該頁面,則用戶將看到意外的行爲。一些版本的IE會給你一些會話超時錯誤IIRC,其他瀏覽器可能會更優雅地處理它。

如果用戶爲該頁添加書籤並在稍後的日期使用GET請求返回給用戶 - 他們將不會看到顯示操作。您的應用可能會引發錯誤,或者可能會呈現索引操作,因爲用戶正在請求諸如http://my.app.com/users之類的網址,該網址在使用GET請求時會映射到索引操作。 2)如果您在沒有重定向到GET請求的情況下呈現show動作並且用戶點擊刷新,您的瀏覽器將重新提交所有相同數據的POST請求,可能會創建您正在創建的任何重複實例。瀏覽器會向用戶發出警告,以便他們可以中止,但這可能會造成混淆和不必要的不​​便。

至於你的問題的第二部分,不太確定是誠實的。我的猜測是,既然你已經更新了有問題的對象,你已經有了它的副本,所以不需要返回它的另一個實例。話雖如此,更新一個對象可能會觸發各種回調,這些回調會修改對象的其他屬性,因此使用這些修改返回更新的對象可能是有意義的。

+1

我同意你對我問題第二部分的回答。你對我的問題的第一部分的回答是有道理的,但是接下來會引出另一個問題:爲什麼在創建或更新失敗之後,出於與前面提到的相同的原因而渲染使用了而不是redirect_to?如果用戶想要將編輯或新頁面加入書籤,該怎麼辦?如果使用了渲染,那麼他們仍然會在「/ whatevers」頁面上(這是錯誤的)。 – Buddy 2010-09-03 20:32:01

+1

如果用戶被重定向到新的/編輯操作,則所有提交的POST數據都將丟失,並且呈現的表單將爲空。你是正確的,用戶可以爲渲染的錯誤頁面添加書籤,並且它會指向錯誤的URL。沒辦法阻止這個AFAIK。 – Sidane 2010-09-04 08:30:26

+0

哦,是的,杜。我錯誤地認爲你可以重定向到新的或編輯頁面,並傳遞一個@object。我錯了。謝謝你讓我變直! – Buddy 2010-09-05 00:03:20

1

在創建或更新時,redirect_to(@whatever)可以清除帖子,以便用戶不會通過刷新重新提交。它還在創建案例的地址欄中顯示正確的網址,該網址發佈到收集路徑(/ whatevers)。

head :ok對更新做出最小響應時,通常情況下您已經擁有dom中的對象。如果您在更新後更新頁面,則標準方法是使用rjs視圖更新dom元素並渲染部分。

+0

我同意你對#1的回答,但我不太確定#2。就像斯丹所說的那樣,這個對象可以通過回調來改變。此外,由於update_attributes的默認行爲是「無聲無息」,即使某些無效的鍵或值傳遞給它(有些屬性受保護或只讀),它有時也會返回true。在這種情況下,DOM中的對象與更新後對象在後端看起來的方式不同。 「Head:ok」可能是可以的,但出於測試目的,我想我可能想在更新後擁有真實對象的副本。 – Buddy 2010-09-03 20:21:46