Mongoid embedded document parent not set in after_initialize callback
I'm trying to reference the parent object of an embedded document from within an after_initialize callback.
Here's a mockup of my setup:
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
This will cause the behavior I don't want:
a = Person.new
a.posts.build
puts "after callback"
p a.posts.first.person
which spits out:
[d][Moe:~]$ ruby test.rb
in callback
nil
after callback
#<Person _id: 4e57b0e开发者_Go百科cba81fe9527000001, _type: nil>
To get the desired behavior, I can manually do this:
b = Person.new
c = Post.new(person: b)
puts "after callback"
p c.person
which gives me:
d][Moe:~]$ ruby test.rb
in callback
#<Person _id: 4e57b386ba81fe9593000001, _type: nil>
after callback
#<Person _id: 4e57b386ba81fe9593000001, _type: nil>
the only problem with that being that it doesn't work whenever an object is being loaded from the DB, in which case one would think that person
would already be set, because it's being loaded from the person, but it's not.
Does anyone know if this is the desired behavior, and if it is can you tell me why? If this isn't the desired behavior, can anyone tell me a workaround?
There are several issues for this problem on GitHub: #613, #815 and #900.
Mongoid v2.2.0 has been released yesterday, but still doesn't include the patch from #900. So there's no simple way to do this.
Depending on your use case, lazy loading might already be enough:
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
精彩评论