5

我有兩個型號,結構如下:Rails的「assign_attributes」不分配嵌套模型

class Wallet < ActiveRecord::Base 
    include ActiveModel::Validations 
    has_one :credit_card 
    accepts_nested_attributes_for :credit_card 

    validates :credit_card, :presence => true 
    validates_associated :credit_card 
    ... 
end 

class CreditCard < ActiveRecord::Base 
    include ActiveModel::Validations 
    belongs_to :wallet 

    validates :card_number, :presence => true 
    validates :expiration_date, :presence => true 
    ... 
end 

我測試我使用RSpec應用程序的功能,我發現了一些奇怪的。如果我使用不符合嵌套模型的驗證條件的屬性創建哈希(例如沒有卡號),然後嘗試執行update_attributes調用,那麼我使用無效的CreditCard返回的錢包對象中返回的內容嵌套模型和適當的錯誤。這是正確的,預期的行爲。

如果我採取相同的哈希雖然和運行assign_attributes,然後save(這是所有update_attributes方法應該做的事,然後我得到返回無效錢包對象與完全無嵌套的對象。這是爲什麼?如何才能我更新所有嵌套的屬性值,並檢查錯誤,不保存

回答

4

首先的 - 你不必include ActiveModel::Validations b因爲他們來與ActiveRecord::Base

第二 - 是的update_attributes在內部使用assign_attributes所以基本上它應該按預期工作。

如果你沒有任何attr_accessibleattr_protectedwith/without_protection選項,我假設你正在創建正確的散列與

{'credit_card_attributes' => {'card_number' => ''}} 

那麼它看起來像軌道內某種錯誤的。但在同一時間,我只是檢查它,似乎它工作正常。

以上,如果你想只是爲了檢查驗證不保存在測試對象,然後只需運行

Wallet.new(hash_with_attributes).valid? 

它應該返回正確的錢包對象嵌套CREDIT_CARD並在其上的錯誤。

1

這聽起來像Strong Params(Rails 4功能)可能會剝離嵌套屬性,並且由於您的驗證在沒有它們的情況下失敗,您將被重定向回錯誤的編輯頁面,並且您的信用卡nested_attributes現在爲零。

也許這會有所幫助。 https://stackoverflow.com/a/17532811/793330

保存和update_attributes不是一回事。保存將保存整個對象,而更新只會更改您傳遞給它的已更改的項目。略有不同,但差別不大。