# To\_json() does not have behave like to\_xml builder and block support

**URL:** <https://www.ruby-forum.com/t/to-json-does-not-have-behave-like-to-xml-builder-and-block-support/152553>\
**Category:** Rails\
**Created:** [November 5, 2008, 3:50am UTC](https://www.ruby-forum.com/t/to-json-does-not-have-behave-like-to-xml-builder-and-block-support/152553 "2008-11-05T03:50:02Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![rubynewbie](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/58f4c7/32.png) [@rubynewbie](https://www.ruby-forum.com/u/rubynewbie)\
**Post date:** [November 5, 2008, 3:50am UTC](https://www.ruby-forum.com/t/to-json-does-not-have-behave-like-to-xml-builder-and-block-support/152553/1 "2008-11-05T03:50:02Z")

</div>

Our Rails application needs to support both xml and json formats. In  
some cases, we need to return custom XML that spans several objects  
and associations. I’ve been able to write custom to\_xml methods that  
use the builder and block functionality. When trying the same thing  
with the to\_json method, I failed to get the same result.

Basically to\_xml has this signature: to\_xml(options = {}, &block).  
I’ve perused around and it appears to\_json has this signature:  
to\_json(options = {}). Is there a version of to\_json that will yield  
to a block  
and provide the json builder? Can someone please tell me if I’ve done  
something wrong with the code below? Is there is a plugin or newer  
version of Rails that will add the same support for to\_json that  
to\_xml supports?

Here is the relevant code

class Conference \< ActiveRecord::Base  
has\_many :courses, :dependent =\> :destroy  
end

class Course \< ActiveRecord::Base  
belongs\_to :conference  
has\_many :sessions, :dependent =\> :destroy  
has\_one :manual

```
        # just a place holder method so we can serialize it

```

def pre\_requisite  
“An open mind”  
end  
end

class Session \< ActiveRecord::Base  
belongs\_to :courses  
has\_one :presentation, :dependent=\>:destroy

```
        # just a place holder method so we can serialize it

```

def maximum\_capacity\_reached?  
false;  
end  
end

class Presentation \< ActiveRecord::Base  
belongs\_to :session  
belongs\_to :instructor  
end

class Manual \< ActiveRecord::Base  
belongs\_to :course  
end

class Instructor \< ActiveRecord::Base  
end

Now let’s suppose I have a controller that will return the full detail  
of a conference and needs all of the related data and will also  
serialize some custom methods.  
class ConferencesController \< ApplicationController

# GET /conferences/:id

def show  
conference\_id = params[:id]

```
respond_to do |format|
  format.html # unsupported
  format.json {
    render(:json=>Conference.full_json(conference_id))
  }
  format.xml {
    render(:xml=>Conference.full_xml(conference_id))
  }
end

```

end  
end

So I’ve extended the conference class so that it can build this nested  
xml along with the result of selective methods on various classes.  
this code uses the fact that to\_xml has this signature: to\_xml(options  
= {}, &block)

class Conference \< ActiveRecord::Base  
has\_many :courses, :dependent =\> :destroy

def slogan  
“#{name}: Be here or be in the dark!”  
end

def self.full\_xml(conference\_id)  
# ensure we’ve loaded the full structure in the most efficient  
manner  
conference = Conference.find(conference\_id, :include=\>{:courses =\>  
[:manual, {:sessions=\>:presentation}]})

```
# extract detailed hierarchical xml
conference.to_xml do |xml|
  xml.slogan conference.slogan # output the banner

  #iterate courses and any custom methods
  xml.courses{
    conference.courses.each do |course|
      course.to_xml(:builder=>xml, :skip_instruct => true) do |

```

xml\_course|  
xml\_course.sessions{  
#iterate sessions and any custom methods  
course.sessions.each do |session|  
session.to\_xml(:builder=\>xml\_course, :skip\_instruct =\>  
true)  
do |xml\_course\_session|  
xml\_course\_session.is\_at\_capacity  
session.maximum\_capacity\_reached?  
end  
end  
}  
end  
end  
}  
end  
end

def self.full\_json(conference\_id)  
# ensure we’ve loaded the full structure in the most efficient  
manner  
conference = Conference.find(conference\_id, :include=\>{:courses =\>  
[:manual, {:sessions=\>:presentation}]})

```
debugger()

# extract detailed hierarchical xml
conference.to_json do |json|
  json.slogan conference.slogan # output the banner

  #iterate courses and any custom methods
  json.courses{
    conference.courses.each do |course|
      course.to_json(:builder=>json, :skip_instruct => true) do |

```

json\_course|  
json\_course.sessions{  
#iterate sessions and any custom methods  
course.sessions.each do |session|  
session.to\_json(:builder=\>json\_course, :skip\_instruct =\>  
true)  
do |json\_course\_session|  
json\_course\_session.is\_at\_capacity  
session.maximum\_capacity\_reached?  
end  
end  
}  
end  
end  
}  
end  
end  
end

## When I invoke the method, via [http://localhost:3000/conferences/1.xml](http://localhost:3000/conferences/1.xml), I get the desired generated XML output: 2008-11-04T13:59:41-08:00 1 Ruby Live 2008-11-04T13:59:41-08:00 Ruby Live: Be here or be in the dark!
- 1 Action Controller: In Depth 2008-11-04T13:59:41-08:00 1 2008-11-04T13:59:41-08:00 - - 1 2008-11-04T13:59:41-08:00 2008-12-04T15:59:41-08:00 1 4 101 2008-12-04T13:59:41-08:00 2008-11-04T13:59:41-08:00 false - 1 2008-11-04T13:59:41-08:00 2008-12-05T15:59:41-08:00 2 4 101 2008-12-05T13:59:41-08:00 2008-11-04T13:59:41-08:00 false + 1 Active Record: In Depth 2008-11-04T13:59:41-08:00 2 2008-11-04T13:59:41-08:00 - - 2 2008-11-04T13:59:41-08:00 2008-12-04T17:59:41-08:00 3 5 201 2008-12-04T15:59:41-08:00 2008-11-04T13:59:41-08:00 false - 2 2008-11-04T13:59:41-08:00 2008-12-05T17:59:41-08:00 4 5 201 2008-12-05T15:59:41-08:00 2008-11-04T13:59:41-08:00 false

When I invoke the method, via [http://localhost:3000/conferences/1.json](http://localhost:3000/conferences/1.json),  
I get the following undesired generated json output. Basically the  
builder and block that acts on to\_xml is ignored or defunct.  
{“name”: “Ruby Live”, “updated\_at”: “2008/11/04 13:59:41 -0800”, “id”:  
1, “created\_at”: “2008/11/04 13:59:41 -0800”}

I need to support both xml and json formats while returning the same  
data. Can someone please tell me what if there is a plugin or newer  
version of Rails that will add this same support for to\_json that  
to\_xml supports?Our application needs to support both xml and json  
formats while returning the same data. In some cases, we need to  
return custom XML that spans several objects and associations. I’ve  
been able to write custom to\_xml methods that use the builder and  
block functionality. When trying the same thing with the to\_json  
method, I failed to get the same result. Can someone please tell me  
if I’ve done something wrong with the code below? Is there is a  
plugin or newer version of Rails that will add the  
same support for to\_json that to\_xml supports?

Here is the relevant code

class Conference \< ActiveRecord::Base  
has\_many :courses, :dependent =\> :destroy  
end

class Course \< ActiveRecord::Base  
belongs\_to :conference  
has\_many :sessions, :dependent =\> :destroy  
has\_one :manual

```
        # just a place holder method so we can serialize it

```

def pre\_requisite  
“An open mind”  
end  
end

class Session \< ActiveRecord::Base  
belongs\_to :courses  
has\_one :presentation, :dependent=\>:destroy

```
        # just a place holder method so we can serialize it

```

def maximum\_capacity\_reached?  
false;  
end  
end

class Presentation \< ActiveRecord::Base  
belongs\_to :session  
belongs\_to :instructor  
end

class Manual \< ActiveRecord::Base  
belongs\_to :course  
end

class Instructor \< ActiveRecord::Base  
end

Now let’s suppose I have a controller that will return the full detail  
of a conference and needs all of the related data and will also  
serialize some custom methods.  
class ConferencesController \< ApplicationController

# GET /conferences/:id

def show  
conference\_id = params[:id]

```
respond_to do |format|
  format.html # unsupported
  format.json {
    render(:json=>Conference.full_json(conference_id))
  }
  format.xml {
    render(:xml=>Conference.full_xml(conference_id))
  }
end

```

end  
end

So I’ve extended the conference class so that it can build this nested  
xml along with the result of selective methods on various classes.  
class Conference \< ActiveRecord::Base  
has\_many :courses, :dependent =\> :destroy

def slogan  
“#{name}: Be here or be in the dark!”  
end

def self.full\_xml(conference\_id)  
# ensure we’ve loaded the full structure in the most efficient  
manner  
conference = Conference.find(conference\_id, :include=\>{:courses =\>  
[:manual, {:sessions=\>:presentation}]})

```
# extract detailed hierarchical xml
conference.to_xml do |xml|
  xml.slogan conference.slogan # output the banner

  #iterate courses and any custom methods
  xml.courses{
    conference.courses.each do |course|
      course.to_xml(:builder=>xml, :skip_instruct => true) do |

```

xml\_course|  
xml\_course.sessions{  
#iterate sessions and any custom methods  
course.sessions.each do |session|  
session.to\_xml(:builder=\>xml\_course, :skip\_instruct =\>  
true)  
do |xml\_course\_session|  
xml\_course\_session.is\_at\_capacity  
session.maximum\_capacity\_reached?  
end  
end  
}  
end  
end  
}  
end  
end

def self.full\_json(conference\_id)  
# ensure we’ve loaded the full structure in the most efficient  
manner  
conference = Conference.find(conference\_id, :include=\>{:courses =\>  
[:manual, {:sessions=\>:presentation}]})

```
debugger()

# extract detailed hierarchical xml
conference.to_json do |json|
  json.slogan conference.slogan # output the banner

  #iterate courses and any custom methods
  json.courses{
    conference.courses.each do |course|
      course.to_json(:builder=>json, :skip_instruct => true) do |

```

json\_course|  
json\_course.sessions{  
#iterate sessions and any custom methods  
course.sessions.each do |session|  
session.to\_json(:builder=\>json\_course, :skip\_instruct =\>  
true)  
do |json\_course\_session|  
json\_course\_session.is\_at\_capacity  
session.maximum\_capacity\_reached?  
end  
end  
}  
end  
end  
}  
end  
end  
end

## When I invoke the method, via [http://localhost:3000/conferences/1.xml](http://localhost:3000/conferences/1.xml), I get the desired generated XML output: 2008-11-04T13:59:41-08:00 1 Ruby Live 2008-11-04T13:59:41-08:00 Ruby Live: Be here or be in the dark!
- 1 Action Controller: In Depth 2008-11-04T13:59:41-08:00 1 2008-11-04T13:59:41-08:00 - - 1 2008-11-04T13:59:41-08:00 2008-12-04T15:59:41-08:00 1 4 101 2008-12-04T13:59:41-08:00 2008-11-04T13:59:41-08:00 false - 1 2008-11-04T13:59:41-08:00 2008-12-05T15:59:41-08:00 2 4 101 2008-12-05T13:59:41-08:00 2008-11-04T13:59:41-08:00 false + 1 Active Record: In Depth 2008-11-04T13:59:41-08:00 2 2008-11-04T13:59:41-08:00 - - 2 2008-11-04T13:59:41-08:00 2008-12-04T17:59:41-08:00 3 5 201 2008-12-04T15:59:41-08:00 2008-11-04T13:59:41-08:00 false - 2 2008-11-04T13:59:41-08:00 2008-12-05T17:59:41-08:00 4 5 201 2008-12-05T15:59:41-08:00 2008-11-04T13:59:41-08:00 false

When I invoke the method, via [http://localhost:3000/conferences/1.json](http://localhost:3000/conferences/1.json),  
I get the following undesired generated json output. Basically the  
builder and block that acts on to\_xml is ignored or defunct.  
{“name”: “Ruby Live”, “updated\_at”: “2008/11/04 13:59:41 -0800”, “id”:  
1, “created\_at”: “2008/11/04 13:59:41 -0800”}

I need to support both xml and json formats while returning the same  
data. Can someone please tell me what if there is a plugin or newer  
version of Rails that will add this same support for to\_json that  
to\_xml supports?

---

<div class="post-metadata">

**Author:** ![rubynewbie](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/r/58f4c7/32.png) [@rubynewbie](https://www.ruby-forum.com/u/rubynewbie)\
**Post date:** [November 5, 2008, 9:55am UTC](https://www.ruby-forum.com/t/to-json-does-not-have-behave-like-to-xml-builder-and-block-support/152553/2 "2008-11-05T09:55:05Z")

</div>

On 5 Nov 2008, at 02:49, RubyNewbie wrote:

> to a block  
> and provide the json builder? Can someone please tell me if I’ve done  
> something wrong with the code below? Is there is a plugin or newer  
> version of Rails that will add the same support for to\_json that  
> to\_xml supports?

I don’t believe there is a json builder - it’s just not how the json  
stuff in rails works. basically there’s an obvious implementation of  
to\_json for hashes and arrays, everything else just hangs off that (so  
to\_json on an activerecord object basically takes the hash of  
attributes (module except/only etc… options) and calls to\_json on it)

Fred
