2011-04-11 99 views
4

我一直在使用Mongoid大約3個月,並且我已經設法完成了我需要的任何東西,這要感謝那裏的優秀文檔和資源。Mongoid,與嵌入式文檔與時間戳和版本控制混淆?

但回去改進一些東西,我做了幾個背,我肯定在嵌入式文檔上掙扎很多。

概括地說什麼,我試圖做的,是維護版本和時間戳嵌入式文件,但我不能設法做。

這裏是我的模型的相關部分:

class Content 
    include Mongoid::Document 
    include Mongoid::Timestamps 
    include Mongoid::Paranoia 

    embeds_many :localized_contents 
    accepts_nested_attributes_for :localized_contents 
end 

class LocalizedContent 
    include Mongoid::Document 
    include Mongoid::Timestamps 
    include Mongoid::Paranoia 
    include Mongoid::Versioning 

    embedded_in :content, :inverse_of => :localized_contents 
end 

這裏沒有什麼很複雜,一切關於內容模型的行爲工作正常,但是LocalizedContent模型沒有表現我期待的方式,所以我的期望要麼得到理順,要麼我需要幫助解決我做錯了什麼。

要創建一個新的嵌入文檔我做到以下幾點:

my_content = Content.find(params[:id]) 
my_content.localized_contents.build(params[:localized_content]) 
if parent.save 
#redirect, etc. 
end 

此作品在某種意義上說,它成功地創建了正確的內容的新的嵌入文檔,但是我留下了零

時間戳字段

現在,如果我嘗試更新localized_content:

my_content = Content.find(params[:content_id]) 
localized_content = my_content.localized_contents.find(params[:id]) 

現在,如果我這樣做:localized_content.update_attributes(params[:localized_content])我得到以下錯誤:

=> Mongoid::Errors::InvalidCollection: Access to the collection for LocalizedContent is not allowed since it is an embedded document, please access a collection from the root document. 

不夠公平,那麼我更新原子上的本地化內容的字段並保存父:

localized_content.fieldA = "value" 
localized_content.fieldB = "value" 
localized_content.fieldC = "value" 

my_content.save 

這個工作在正常更新的本地化內容,但是: - timesteamps(udpated_at和created_at)仍然沒有 - 版本沒有收到當前localized_content的副本,版本也沒有增加!

因此,正如我在許多場合在這個組,在網絡上的一些論壇上閱讀時,回調不會觸發對性能的原因嵌入的文檔,因爲我呼籲保存父。再次,足夠寬容,但正如在這些地方建議的,我應該調用保存在嵌入式文檔,而不是...但是,怎麼!?!?!因爲每次我做的時候,我得到了可怕的:

=> Mongoid::Errors::InvalidCollection: Access to the collection for LocalizedContent is not allowed since it is an embedded document, please access a collection from the root document. 

更是這樣,我想手動調用回調的版本在我的嵌入式:localized_content.revise,並再次同樣的錯誤:

=> Mongoid::Errors::InvalidCollection: Access to the collection for LocalizedContent is not allowed since it is an embedded document, please access a collection from the root document. 

我要瘋了!請幫忙。我做錯了什麼?應該如何嵌入文檔來創建和(甚至手動我不在乎)更新,所以我可以調用適當的回調來更新時間戳和版本?

感謝,

亞歷

PS:我使用的鐵軌3.0.3和2.0 mongoid。1

+0

爲您的發佈提供一個合理的主題也許是獲得幫助的第一步。像「請幫助」的東西不屬於主題! – 2011-04-11 04:41:33

+0

夠公平,更新! – Alex 2011-04-11 04:45:21

回答

4

嘗試使用create而不是build。 EmbeddedDoc.build和EmbeddedDoc.new不會觸發任何保存回調(因爲沒有保存),並且保存父文檔不會調用嵌入的子回調(性能決策)。 EmbeddedDoc.create 應該雖然會觸發嵌入式文檔回調。

my_content = Content.find(params[:id]) 
puts my_content.localized_contents.create(params[:localized_content]) 
13

萬一這個答案仍然是有用的人,Mongoid又增加了一個標籤,這使得當父對象被保存回調嵌入式子對象運行。

你的父對象,現在應該是這樣的:

class Content 
    include Mongoid::Document 
    include Mongoid::Timestamps 
    include Mongoid::Paranoia 

    embeds_many :localized_contents, cascade_callbacks: true 
    accepts_nested_attributes_for :localized_contents 
end 

這就是它!現在,保存父對象將在子對象上運行回調(並且Mongoid::Timestamps足夠智能,只能在實際更改的對象上運行)。這些信息位於嵌入式文檔頁面底部的mongoid文檔中。