Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to customize the to_json method in rails3?

I want to convert an array of Place objects to json, I've been doing it like this:

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

The only problem is that every place in the @places array has an associated tag list that doesn't get included. I'm using the acts_as_taggable_on gem to handle tags, so to get the tag list for a place I need to say place.tag_list.

What do I have to do to get the tag_list included for each place in the javascript array? I think I'll need to write my own to_json method but I don't know how.

EDIT

It turns out that this is easier than I realized. I was able to say this:

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. Every tag has an id and name, what I really want is just a list with tag names in it.

like image 452
lashleigh Avatar asked Jan 16 '11 02:01

lashleigh


2 Answers

The to_json method also accepts an argument called methods. This argument allows you to specify 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 to produce tag names, but each tag has a method to give you its name, you could add a method inside your Place model to produce a list of tag names like so:

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

Then you could get your places json with tag_names like this:

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

This technique will work for any computed attributes you'd like to add to a model's json representation.

like image 132
Benson Avatar answered Sep 19 '22 13:09

Benson


Within your Place class, you can override to_json. In Rails 3, you should override 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 %>;
like image 31
Kyle Wild Avatar answered Sep 20 '22 13:09

Kyle Wild