2013-03-20 95 views
4

在Mongoid中,將文檔推入embeds_many關係會自動將文檔保留到數據庫中。通常情況下,這很好,但當我需要跟蹤對嵌入式文檔的更改時遇到問題。Mongoid embeds_many:推送文檔而不保存以保留髒狀態

假設你有兩種型號:

class List 
    include Mongoid::Document 
    embeds_many :items 
    field :title 
end 

class Item 
    include Mongoid::Document 
    embedded_in :list 
    field :name 
end 

這正好和.changes屬性:

list = List.new(title: 'List title') 
list.save #list is now persisted 
item = Item.new(name: 'Item name') 
item.changes #returns Hash with {'name' => [nil, 'Item name']} 
list.items << item #saves item to database under the hood 
item.changes #returns empty Hash, because item was autosaved with list 

我可以用item.previous_changes檢查是共推項目進入榜單前所做的更改,但在我的具體情況下,這會給我帶來各種麻煩,讓事情變得易於管理。

我想什麼來實現的,是能夠初始化一個Item文檔,然後而不立即將它保持它(通過<<push)添加到list

我知道,Mongoid確實提供了一個選項來設置embeds_many關係沒有持續性(見http://mongoid.org/en/mongoid/docs/relations.html#embeds_many):

list.items.build(name: 'Another item') 

的問題存在着Mongoid爲您創建項目實例。在我的情況下,embeds_many關係中的文檔可能是項目的子類(例如SpecialItem < Item),這對於build不起作用。但如果有人知道解決這個限制的方法,我也很樂意接受它作爲答案。

回答

2

要跟進「建設一個子類」問題,使用例如,您可以:

list.items.build({ 
    name: "Another Item" 
}, SpecialItem) 

要指定要Mongoid打造適合你的(子)類。

4

回答我自己的問題:通過將父文檔分配給子代來解決問題,而不是將子代添加到列表或子代。

繼續在上面的例子中,你應該做的

item.list = list #no database query 

代替

list.items << item #automatic database insert 

設置父 - 沒有自動保存任何東西到數據庫孩子參考。