2011-01-16 15 views
5

voglio convertire un array di oggetti Luogo a JSON, ho fatto in questo modo:Come personalizzare il metodo to_json in rails3?

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

L'unico problema è che ogni luogo nella matrice @places ha una lista di tag associata che doesn' t incluso. Sto usando la gemma act_as_taggable_on per gestire i tag, quindi per ottenere l'elenco di tag per un posto che devo dire place.tag_list.

Che cosa devo fare per ottenere la tag_list inclusa per ogni posizione nell'array javascript? Penso che dovrò scrivere il mio metodo to_json ma non so come.

EDIT

Si scopre che questo è più facile di quanto pensassi. Sono stato in grado di dire questo:

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

L'unico problema è che questo include ulteriori informazioni su ogni tag che ho davvero bisogno. Ogni tag ha un ID e un nome, quello che voglio veramente è solo una lista con i nomi dei tag.

risposta

5

Il metodo to_json accetta anche un argomento chiamato methods. Questo argomento consente di specificare metodi che dovrebbero essere chiamati e inclusi nella rappresentazione json dell'oggetto. Dal momento che lei ha detto che si dispone di un metodo chiamato tag_list, si può fare questo:

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

Se, per qualche motivo, non si dispone di un metodo per produrre i nomi dei tag, ma ogni tag ha un metodo per darvi il suo nome, si potrebbe aggiungere un metodo all'interno del vostro modello di Place per produrre un elenco di nomi di tag in questo modo:

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

allora si potrebbe ottenere i vostri posti JSON con tag_names come questo:

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

Questa tecnica funzionerà per tutti gli attributi calcolati che desideri aggiungere alla rappresentazione JSON di un modello.

+0

+1 - bella! Posso pensare a un milione di posti che userò questo :) –

2

All'interno della classe Luogo, è possibile ignorare to_json. In Rails 3, si dovrebbe ignorare as_json invece:

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

quindi modificare il codice per:

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

Ok, io continuo a non capire ciò che il metodo sarà simile però. Non capisco come includere ogni posizione tag_list. – lashleigh

+0

Mentre funzionerebbe, è un po 'pesante. – Benson

+0

d'accordo, la risposta di Benson è fantastica –

1

risposta di Benson non funziona se si sta chiamando

render :json => @places 

nel PlacesController. Dovrai aggiungere il seguente codice nel modello 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 

Speranza che aiuta a qualcun altro. Ho dovuto esaminare il codice sorgente per capire perché Array.to_json non è la stessa di Array.each { |a| a.to_json }

Problemi correlati