2011-08-26 78 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。 –