Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mongoid document to_json including all embedded documents without ':include' on each one

Tags:

json

ruby

mongoid

Given an arbitrary mongoid document how do i convert it to JSON and include any embedded structures without specifically including those structures in my to_json statement.

For example:

#!/usr/bin/env ruby
require 'mongoid'
require 'json'
require 'pp'

class Doc
  include Mongoid::Document
  include Mongoid::Timestamps

  field :doc_specific_info    , type: String 

  embeds_many :persons
end

class Person
  include Mongoid::Document

  field :role                  , type: String
  field :full_name             , type: String

  embeds_many :addresses
  embedded_in :Doc
end

class Address
  include Mongoid::Document

  field :full_address       , type: String

end

doc = Doc.new
doc.doc_specific_info = "TestReport"

p = Person.new
p.role = 'buyer'
p.full_name = 'JOHN DOE'
doc.persons << p

a = Address.new
a.full_address =  '1234 nowhere ville' 
doc.persons.first.addresses << a

# THIS STATEMENT
pp JSON.parse(doc.to_json(:include => { :persons => { :include => :addresses } }  ) )
#   GIVES ME
#   {"_id"=>"4ee0d30fab1b5c5743000001",
#    "created_at"=>nil,
#    "doc_specific_info"=>"TestReport",
#    "updated_at"=>nil,
#    "persons"=>
#     [{"_id"=>"4ee0d30fab1b5c5743000002",
#       "full_name"=>"JOHN DOE",
#       "role"=>"buyer",
#       "addresses"=>
#        [{"_id"=>"4ee0d30fab1b5c5743000003",
#          "full_address"=>"1234 nowhere ville"}]}]}

# THIS STATEMENT
pp JSON.parse(doc.to_json() )
#  GIVES ME
#  {"_id"=>"4ee0d2f8ab1b5c573f000001",
#   "created_at"=>nil,
#    "doc_specific_info"=>"TestReport",
#     "updated_at"=>nil}

So what I want is a statement something like this:

   # FOR A STATEMENT LIKE THIS
    pp JSON.parse(doc.to_json( :everything }  ) )
    #   TO GIVE ME THE COMPLETE DOCUMENT LIKE SO:
    #   {"_id"=>"4ee0d30fab1b5c5743000001",
    #    "created_at"=>nil,
    #    "doc_specific_info"=>"TestReport",
    #    "updated_at"=>nil,
    #    "persons"=>
    #     [{"_id"=>"4ee0d30fab1b5c5743000002",
    #       "full_name"=>"JOHN DOE",
    #       "role"=>"buyer",
    #       "addresses"=>
    #        [{"_id"=>"4ee0d30fab1b5c5743000003",
    #          "full_address"=>"1234 nowhere ville"}]}]}

Does such a statement exist? If not then is my only alternative recusing the structure of the document and producing the proper includes myself? If there is another way to visualize the whole document that would be better?

like image 822
Craig Wetzelberger Avatar asked Dec 08 '11 15:12

Craig Wetzelberger


2 Answers

This was answered by rubish in the forum but he didn't post an answer so I am doing that.

The answer is to use "doc.as_document.as_json" which will give you the whole document.

pp doc.as_document.as_json
like image 139
Craig Wetzelberger Avatar answered Nov 13 '22 02:11

Craig Wetzelberger


You can override the #to_json method in your document to add all include.

class Person

  def to_json(*args)
    super(args.merge({:include => { :persons => { :include => :addresses } } } )
  end
end

Now you can have all by doing

person.to_json()

If you want return the complete with only :everything option you can do :

class Person

  def to_json(*args)
    if args[0] == :everything
      super(args.merge({:include => { :persons => { :include => :addresses } } } )
    else
      super(args)
    end
  end

end
like image 39
shingara Avatar answered Nov 13 '22 02:11

shingara