2011-01-16 9 views
5

Quiero convertir un conjunto de Coloque los objetos a JSON, que he estado haciendo de esta manera:¿Cómo personalizar el método to_json en rails3?

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

El único problema es que cada lugar en la matriz @places tiene una lista de etiquetas asociado Eso no t ser incluido Estoy usando la etiqueta act_as_taggable_on para manejar etiquetas, así que para obtener la lista de etiquetas para un lugar necesito decir place.tag_list.

¿Qué debo hacer para obtener la lista_tabla incluida para cada lugar en la matriz javascript? Creo que tendré que escribir mi propio método to_json, pero no sé cómo.

EDITAR

Resulta que esto es más fácil de lo que pensaba. Pude decir esto:

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

El único problema es que esto incluye más información sobre cada etiqueta de la que realmente necesito. Cada etiqueta tiene una identificación y un nombre, lo que realmente quiero es solo una lista con los nombres de las etiquetas.

Respuesta

5

El método to_json también acepta un argumento llamado methods. Este argumento le permite especificar métodos que deberían llamarse e incluirse en la representación json del objeto. Puesto que usted ha mencionado que tiene un método llamado tag_list, usted puede hacer esto:

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

Si, por alguna razón, usted no tiene un método para producir los nombres de etiqueta, pero cada etiqueta tiene un método para darle su nombre, se podría añadir un método dentro de su modelo de Place para producir una lista de nombres de etiqueta, así:

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

a continuación, le permitió conocer los lugares JSON con tag_names así:

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

Esta técnica funcionará para cualquier atributo calculado que quiera agregar a la representación json de un modelo.

+0

+1 - ¡agradable! Puedo pensar en un millón de lugares que usaré esto :) –

2

Dentro de su clase Place, puede anular to_json. En Rails 3, debe reemplazar as_json lugar:

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

A continuación, cambiar el código para:

var places = <%= @places.as_json.html_safe %>; 
+0

Ok, todavía no entienden lo que el método se vería sin embargo. No entiendo cómo incluir cada lugar tag_list. – lashleigh

+0

Si bien eso funcionaría, es un poco torpe. – Benson

+0

de acuerdo, la respuesta de Benson es asombrosa –

1

respuesta de Benson no funcionará si está llamando

render :json => @places 

en el PlacesController. Deberá agregar el siguiente código en el modelo Place.

# 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 

Espero que ayude a alguien más. Tuve que mirar a través del código fuente para descubrir por qué Array.to_json no es lo mismo que Array.each { |a| a.to_json }

Cuestiones relacionadas