2012-12-04 193 views
0

不會傳播我有一個嵌套的模型設定:更新的嵌套模型

class Event < ActiveRecord::Base 
    belongs_to :place 
     :place 
    attr_accessible :place_attributes, :reject_if => :all_blank, :allow_destroy => false 

class Place < ActiveRecord::Base 
    has_many :events 
    validates :label, :presence => true, 
     :uniqueness => {:case_sensitive => true, :on => :create } 
    validates :description, :presence => {:on => :create}, 
     :uniqueness => {:case_sensitive => true , :on => :create} 

在測試場景中,W嵌套形式,用戶可以只更新將#標籤屬性,保留所有的其他信息。 。

test "should_update_event_place_data" do 
    put :update, :locale => I18n.locale, :id => @event[:id], 
     :event => { :place_attributes => { label: "a very beautiful place" } } 

這導致到EventsController#更新的請求,接收所述參數:

params 
    {"event"=>{"place_attributes"=>{"label"=>"a very beautiful place"}}, "locale"=>"en", 
    "id"=>"145", "controller"=>"backoffice/events", "action"=>"update"} 

(rdb:1) @event.update_attributes(params[:event]) 
false 
@messages={:"place.description"=>["cannot be blank"] 

但驗證是在創建,而不是更新....沒有驗證錯誤應該被檢測到.. 什麼可能是錯的?

感謝您的幫助

I did more testing 
debugger , right after the test setup (before sending the put request) 
@event_0 
#<Event id: 161, account_id: 3, place_id: 249, slug: "my-new-event-on-2013-01-01-at- edinburgh-united-king...", title: "My New Event" 
@event_0.place 
#<Place id: 249, label: "new fake place",.. 

test request: 
put :update, :locale => I18n.locale, :id => @event_0[:id], :event => { :place_attributes => { label: "a very beautiful place"} } 

params in request are OK, @request/method = PUT 

In EventsController#update 
@event.update_attributes(params[:event]) 
.... I inserted a debug in the Place model... 
(before_validation :i_am_on_create, :on => :create) 
    def i_am_on_create 
    debugger 
    p "CREATING" 
    end 

and it's creating !! don't understand why it's not updating the parent nested model 
+0

你可以發佈測試和相應的控制器代碼的其餘代碼? –

+0

你確定關聯的'description'已經存在嗎?沒有看到你的控制器代碼是不可能的,但是在我看來,雖然「@ event」已經存在,但是當你更新父事件記錄時,會創建「@ event.description」並觸發驗證。只是一個猜測。 –

回答

2

update_attributes不會傳播更新到關聯。如果你看源代碼(http://apidock.com/rails/ActiveRecord/Base/update_attributes),你會發現#save 最終被調用。這是默認的行爲:

# existing resource 'mazeratti car' 
car.name = "Wheelz" 
car.brand.label = "Ferrari" 
car.save 
car.reload 
car.name #=> "Wheelz" 
car.brand.label #=> "Mazeratti" 
如果你想要協會將所有的對象被更新,考慮使用「自動保存」的時間(更新

http://apidock.com/rails/ActiveRecord/Associations/ ClassMethods/belongs_to:選項)

+0

感謝您的信息 – erwin

0

如果你只想要測試的標籤屬性被更新,爲什麼不嘗試在這一領域做update_attribute只,而不是整個「事件」?喜歡的東西:

@event.place_attributes.update_attribute(
     :label => params[:event][:place_attributes][:label] 
) 

沒有測試 - 但你的想法...

+0

感謝您的提示,我測試了: place.update_attributes(:label => params [:event] [:place_attributes] [:label]) 並得到了與驗證相同的問題 @messages = {:description => [ 「不能空白」]} 怪異..驗證是否存在:說明不應該發生.. 所以它不是與嵌套模型相關..而是與驗證選項 – erwin

+0

我相信'update_attributes'觸發整個模型驗證,而'更新屬性'(如我的答案)不。我在上面的註釋中注意到你正在做複數形式:'update_attributes' –

+0

另一方面,它使用update_attributes,需要添加一些額外的大括號來處理多個屬性:t.update_attributes({:a = > 1,:b => 2}) –

0

,以更新嵌套模式解決

,我需要添加模型實例ID:

put :update, :locale => I18n.locale, :id => @event_0[:id], :event => { :place_attributes => { id: @event_0.place[:id], label: "a very beautiful place"} } 

so in:place_attributes,我添加了現有的@ event_0.place [:id],它現在正在更新

我在Anson找到答案在2月17日17:04的底部頁面 accepts_nested_attributes_for with find_or_create?