2012-03-30 64 views
23

我有一個用戶和嵌套檔類別如下:嵌套屬性用途的update_attributes插入,而不是更新

class User < ActiveRecord::Base 
    has_one :profile 
    attr_accessible :profile_attributes 
    accepts_nested_attributes_for :profile 
end 

class Profile < ActiveRecord::Base 
    belongs_to :user 
    attr_accessible :name 
end 

user = User.find(1) 
user.profile.id # => 1 
user.update_attributes(profile_attributes: {name: 'some name'}) 
user.profile.id # => 2 

我不明白爲什麼Rails是扔掉舊的配置文件並創建一個新的。

使用

user.profile.update_attributes({name: 'some name'}) 

剛剛更新如預期的當前配置文件。 但在這種情況下,我沒有利用accepting_nested_attributes_for

有誰知道爲什麼更新發生這種方式?我不想最終沒有連接到任何用戶的配置文件行數據庫。

+0

可能你可以嘗試'user.update_attributes(profile_attributes:{:id => user.profile.id,:name:'some name'})' – 2012-03-30 13:57:48

回答

17

我通過添加update_only選項解決了這個問題:

accepts_nested_attributes_for :profile, update_only: true 

現在新的配置文件只被創建,如果不存在。

+3

我很確定@Winfield的答案是正確的 – jones 2013-02-26 14:35:47

+0

爲什麼不能正常工作?只是好奇.. – light24bulbs 2013-06-13 20:21:11

+0

因爲如果你確實包含了嵌套對象的id,默認值(update_only:false)就可以工作,這很有意義,因爲它是從數據庫中獲取嵌套對象的精確方法。更多信息請閱讀http://apidock.com/rails/ActiveRecord/NestedAttributes/ClassMethods/accepts_nested_attributes_for – lulalala 2014-03-17 04:09:40

21

如果您檢查表單,則需要在Profile對象的嵌套屬性散列中設置id屬性。如果沒有設置id,ActiveRecord會認爲它是一個新對象。例如,如果您有一個ERB表單爲用戶中嵌套的配置文件構建了一組嵌套的「profile_attributes」參數散列的'用戶'參數,則可以爲該配置文件ID包含一個隱藏值,如下所示:

<%= hidden_field "user[profile_attributes][id]", @profile.id %> 
+0

如何在嵌套屬性中設置id屬性配置文件對象? – Glide 2013-08-04 01:34:26

+0

添加了一些示例代碼,顯示如何注入隱藏表單值。 – Winfield 2013-08-04 15:37:11

+0

這不是不是個好主意嗎?因爲用戶可能只是混淆了id值。參考使用'update_only:true'選項@jason表示 – davoclavo 2014-03-12 06:27:05

31

對於Rails 4中有同樣問題的所有人:fields_for已經爲您的嵌套表單添加了id,但您必須允許:id參數。我只允許一個:object_name_id參數,因爲這不會拋出任何錯誤,我花了一些時間,直到我看到這在服務器日誌中。希望這可以幫助別人比我浪費更少的時間:)

+0

是的!謝謝你,這是很難調試,愚蠢強烈的參數! ;-) – andy 2014-04-09 08:17:52

+0

就是這樣! :)謝謝 – XeNoN 2014-06-10 10:31:19

+5

我發現將'config.action_controller.action_on_unpermitted_pa​​rameters'更改爲':raise'而不是默認的':log'會很有幫助。當它在你的臉上炸開時,使調試更容易! https://github.com/rails/strong_parameters#handling-of-unpermitted-keys – styger 2015-05-05 17:41:10

0

我在另一個版本的Rails中遇到了這個問題,我想我會失去理智。 雖然添加update_only => true解決了它,但我認爲這是Rails中某處的錯誤。

在我的情況的症狀:我會得到關聯到belongs_to刪除和新的嵌套對象創建 - 直到我第一次刷新頁面。之後,它正常工作。

在我的情況下,我添加了一個before_save方法到我的嵌套類並打印它保存的內容。 我還在調用update_attributes之前打印了屬性。他們正確設置了「parent_id」。 我還在表格中包含了隱藏的ID字段,沒有變化 - 這是正常的,因爲它已經包括在使用fields_for ...

驚喜:我看到一個更新調用產生兩個保存調用。 第一次保存將具有嵌套的對象標識,但對於belongs_to標識爲空。 - 這樣會更新記錄以將「parent_id」設置爲空。 第二次保存會設置「parent_id」,但它會將嵌套對象標識設置爲null。

正如我所說我通過添加update_only => true來修復它,但我認爲它仍然是一個錯誤。

我想知道上述症狀是否適用於您的案例,以確認這是一個錯誤。