Parent Object In Mongoid Embedded Relation Extensions

embedded-documents, mongoid, mongoid3

Solution

I'm answering this myself for future reference. If anyone has an official and documented way of doing this, please let me know.

After an hour or so of Googling and reading (and re-reading) the Mongoid documentation, I turned to the Mongoid source code. A bit of searching and guesswork lead me to `@base` and its accessor method `base`:

  embeds_many :es do
    def m
      base
    end
  end

and then you can say this:

d = D.find(id)
d.es.m.id == id # true

`base` is documented but the documentation is only there because it is defined using `attr_reader :base` and documentation generated from `attr_reader` calls isn't terribly useful. `base` also works with `has_many` associations.

How did I figure this out? The documentation on extensions mentions `@target` in an example:

embeds_many :addresses do
  #...
  def chinese
    @target.select { |address| address.country == "China"}
  end
end

`@target` isn't what we're looking for, `@target` is the array of embedded documents itself but we want what that array is inside of. A bit of grepping about for `@target` led me to `@base` (and the corresponding `attr_reader :base` calls) and a quick experiment verified that `base` is what I was looking for.

Problem

Given a simple embedded relationship with an extension like this: ``` class D include Mongoid::Document embeds_many :es do def m #... end end end class E include Mongoid::Document embedded_in :d end ``` You can say things like this: ``` d = D.find(id) d.es.m ``` Inside the extension's `m` method, how do access the specific `d` that we're working with?

Original source