How to configure to_json method in rails3?

I want to convert an array of Place objects to json, I did it like this:

var places = <%= @places.to_json.html_safe %>; 

The only problem is that every place in the @places array has a linked tag list that is not included. I use the action_as_taggable_on gem to process tags, so to get a list of tags for a place, I need to specify place.tag_list.

What do I need to do to enable tag_list for every place in the javascript array? I think I will need to write my own to_json method, but I do not know how to do this.

EDIT

It turns out it's easier than I understood. I could say the following:

 var places = <%= @places.to_json(:include => :tags).html_safe %> 

The only problem is that this includes more information about each tag than I really need. Each tag has an id and a name that I really want is just a list with the tag names in it.

+5
json javascript ruby-on-rails-3
source share
4 answers

The to_json method also accepts the methods argument. This argument allows you to specify the methods that should be called and included in the json representation of the object. Since you mentioned that you have a method called tag_list , you can do this:

 var places = <%= @places.to_json(:methods => :tag_list).html_safe %> 

If for some reason you donโ€™t have a method for creating tag names, but each tag has a method that will give you its name, you can add a method inside your Place model to create a list of tag names like this:

 def tag_names tags.collect do |tag| tag.name end end 

Then you can get your json places using tag_names as follows:

 place_json = @places.to_json(:methods => :tag_names) 

This method will work for any computed attributes that you would like to add to the json model view.

+5
source share

In your Place class, you can override to_json. In Rails 3, you should replace as_json instead:

 def as_json (options={}) # add whatever fields you need here end 

Then change your code to:

 var places = <%= @places.as_json.html_safe %>; 
+2
source share

Benson answer will not work if you call

 render :json => @places 

in the PlacesController. You will need to add the following code to the Place model.

 # this method is called on a single instance def to_json(options={}) options[:methods] ||= [] options[:methods] << :tag_names super(options) end # this method is called for each instance in an Array to avoid circular references. def as_json(options={}) options[:methods] ||= [] options[:methods] << :tag_names super(options) end 

Hope this helps someone else. I had to look at the source code to find out why Array.to_json does not match Array.each { |a| a.to_json } Array.each { |a| a.to_json }

+1
source share

I would recommend checking out this post if you are making more complex JSON.

How to override to_json in Rails?

See also these two messages:

http://www.tonyamoyal.com/2011/03/25/recursive-custom-to_json-in-ruby-for-arrays-of-objects-or-nested-objects/

http://jonathanjulian.com/2010/04/rails-to_json-or-as_json/

0
source share

All Articles