2012-04-26 8 views
10

Si è verificato un problema in cui sto lavorando con il metodo as_json e come restituire in modo efficiente l'oggetto in JSON E appartiene anche all'oggetto come JSON, dove l'oggetto appartiene all'oggetto ha il suo oggetto own_to. Il codice probabilmente lo spiegherebbe meglio.Problema di Rails as_json - Come includere oggetti nidificati in modo efficiente?

Il Non-Working Way classe

Alert

class Alert < ActiveRecord::Base 
    belongs_to :message 
    # for json rendering 
    def as_json(options={}) 
     super(:include => :message) 
    end 
end 

classe Message

def as_json(options={}) 
    super(methods: [:timestamp, :num_photos, :first_photo_url, :tag_names], 
      include: { camera: { only: [:id, :name] }, 
         position: { only: [:id, :name, :address, :default_threat_level ]}, 
         images: { only: [:id, :photo_url, :is_hidden]} }) 
    end 

Il problema di questo primo set up è che quando ho un oggetto Alert e chiama

alert.as_json() 

ho tutti gli attributi di allarme e tutti gli attributi dal messaggio, ma nessuno degli altri attributi dal messaggio che voglio, come la fotocamera, posizione, ecc

Ecco il "E 'di lavoro, ma probabilmente non modo corretto design"

Alert Classe

class Alert < ActiveRecord::Base 

    belongs_to :message 

    # for json rendering 
    def as_json(options={}) 
     super().merge(:message => message.as_json) 
    end 
end 

Messaggi Classe

# for json rendering 
    def as_json(options={}) 
    super(methods: [:timestamp, :num_photos, :first_photo_url, :tag_names]) 
      .merge(:camera => camera.as_json) 
      .merge(:position => position.as_json) 
      .merge(:images => images.as_json) 
    end 

In questa seconda installazione, ottengo tutti gli attributi nidificati di Messaggi come desidero.

La mia domanda, mi manca qualche convenzione Rails per farlo correttamente? Sembra che ci sarebbe/dovrebbe essere un modo più semplice.

risposta

3

Quale versione di Rails stai utilizzando? Questo è un bug noto nelle versioni precedenti di Rails, apparentemente risolto con this pull request. La tua sintassi sembra giusta per me, quindi forse questo è il tuo problema?

Come parte, è anche possibile effettuare il checkout del nuovo active_model_serializers da Jose Valim (membro principale di Rails). Potrebbe almeno consentirvi di aggirare il problema in modo più elegante.

+0

Bene, sembra che l'abbiano risolto con la richiesta pull, ma non l'hanno mai inserito in una versione.Grazie per il link, ha chiarito alcuni problemi. – bluedevil2k

+1

Per la cronaca, quello che ho ottenuto da quel PR è: 1) prova ad usare una gem specifica per json api (preferisco i serializzatori di modelli attivi) 2) Se non vuoi/non puoi farlo, sovrascrivi 'serialized_hash 'invece di' as_json' in tutti i tuoi modelli. Sostituisci 'as_json' con' serialized_hash'. I tuoi modelli renderanno correttamente le dipendenze incluse. – kikito

+0

grazie kikito, correzione minore, è 'serializable_hash' – trans1t

1

Si consiglia di dare un'occhiata a RABL (acronimo di Ruby API Builder Language) gem (railscast, github). Ti offre un DSL per definire la struttura della risposta JSON (e anche XML) nei modelli (come Haml o CoffeeScript). Supporta anche i partial.

7

La migliore risposta per me era usare serializable_hash. @kikito ha toccato questo nel suo commento, ma c'era un errore di battitura che gli impediva di funzionare. Non è , è serializable_hash.

Letteralmente basta trovare + sostituire as_json con serializable_hash e questo errore scompare. (Non è ancora stato risolto in Rails 4.0.2 di oggi). Avrai anche il vantaggio di avere un tempo più semplice per implementare un'API XML in seguito (alcune persone lo usano ancora!).

+1

grazie, ha funzionato per me – toby

Problemi correlati