2011-08-26 52 views
2

我想從after_initialize回調中引用嵌入式文檔的父對象。Mongoid嵌入式文檔父母未設置在after_initialize回調

這是我設置的樣機:

require 'mongo' 
require 'mongoid' 

connection = Mongo::Connection.new 
Mongoid.database = connection.db('playground') 

class Person 
    include Mongoid::Document 

    embeds_many :posts 
end 

class Post 
    include Mongoid::Document 

    after_initialize :callback_one 

    embedded_in :person, :inverse_of => :post 

    def callback_one 
    puts "in callback" 
    p self.person 
    end 
end 

這將導致的行爲,我不想要的:它吐出

a = Person.new 
a.posts.build 
puts "after callback" 
p a.posts.first.person 

[d][Moe:~]$ ruby test.rb 
in callback 
nil 
after callback 
#<Person _id: 4e57b0ecba81fe9527000001, _type: nil> 

要獲得期望的行爲,我可以手動做到這一點:

b = Person.new 
c = Post.new(person: b) 
puts "after callback" 
p c.person 

這給了我:

d][Moe:~]$ ruby test.rb 
in callback 
#<Person _id: 4e57b386ba81fe9593000001, _type: nil> 
after callback 
#<Person _id: 4e57b386ba81fe9593000001, _type: nil> 

有了這樣,每當被從數據庫中裝入的對象,在這種情況下,人們可能會認爲person將已經設定它不工作的唯一問題,因爲它是從人身上加載的,但事實並非如此。

有誰知道這是否是所需的行爲,如果是的話,你能告訴我爲什麼嗎? 如果這不是所需的行爲,任何人都可以告訴我一個解決方法嗎?

+0

這個問題似乎在Mongoid 3堅持爲好。 – Dex

回答

1

GitHub上存在以下幾個問題:#613,#815#900

昨天發佈了Mongoid v2.2.0,但仍不包含來自#900的補丁。所以沒有簡單的方法來做到這一點。

根據您的使用情況下,延遲加載可能已經足夠:

class Post 
    include Mongoid::Document 

    embedded_in :person, :inverse_of => :post 

    # This won't work yet. 
    # 
    # after_build :init 
    # 
    # def init 
    # @xyz = person.xyz 
    # end 

    def xyz 
    @xyz ||= person.xyz 
    end 

    def do_something 
    xyz.do_some_magic 
    end 
end 
+0

感謝您的解決方法,我還沒有嘗試過懶加載,我想我會等待#900。 –