2010-01-18 14 views
118

Supponiamo che tu sia nel controller degli utenti e desideri ottenere una risposta JSON per una richiesta di show, sarebbe bello se tu potessi creare un file nelle tue viste/utenti/dir, chiamato show.json e dopo i tuoi utenti L'azione #show è completata, esegue il rendering del file.In Rails, come si esegue il rendering di JSON utilizzando una vista?

Attualmente è necessario fare qualcosa sulla falsariga di:

def show 
    @user = User.find(params[:id]) 
    respond_to do |format| 
    format.html 
    format.json{ 
     render :json => @user.to_json 
    } 
    end 
end 

Ma sarebbe bello se si può solo creare un file show.json che automaticamente viene reso in questo modo:

def show 
    @user = User.find(params[:id]) 
    respond_to do |format| 
    format.html 
    format.json 
    end 
end 

Questo mi avrebbe risparmiato un sacco di dolore, e avrebbe lavato via quella sensazione orribilmente sporca che ottengo quando renderò il mio json nel controller

+0

Guardando questo post ora, sembra che questo non mi salverà molto, ma ho casi più complicati, credimi quando dico che questo mi sta causando mal di testa – Matthew

+1

In Rails 3, puoi semplicemente chiamare 'format.json' con un file 'show.json.erb'. Vedi la mia risposta. –

risposta

61

Dovresti essere in grado di fare qualcosa come s nel vostro respond_to blocco:

format.json render :partial => "users/show.json" 

che renderà il modello in app/views/users/_show.json.erb.

+5

Questo è buono, ma troverete rapidamente erb è un modo doloroso per generare JSON. Controlla la mia risposta per alcune alternative. – tybro0103

+1

C'è un modo per farlo senza usare un partial? –

53

Prova ad aggiungere una vista users/show.json.erb Questo dovrebbe essere reso quando si effettua una richiesta per il formato JSON, e si ottiene il vantaggio di esso che è reso da Erb troppo, così il vostro file potrebbe essere simile a questo

{ 
    "first_name": "<%= @user.first_name.to_json %>", 
    "last_name": "<%= @user.last_name.to_json %>" 
} 
+9

Si potrebbe voler usare '@ user.first_name.to_json' invece di' escape_javascript'. Ci sono alcune sottili differenze tra ciò che JS consente e ciò che è * rigorosamente * JSON. (E queste differenze stanno diventando importanti mentre i browser implementano i propri parser JSON.) –

+0

Grazie per il suggerimento; Ho aggiornato la risposta. – erik

+1

Probabilmente dovresti cambiare le virgolette singole in virgolette, dato che JSON (a differenza di JS) accetta solo stringhe tra virgolette doppie. –

9

Basta aggiungere show.json.erb file con il contenuto

<%= @user.to_json %> 

a volte è utile quando avete bisogno di alcuni metodi di supporto extra che non sono disponibili in controllo, vale a dire image_path(@user.avatar) o qualcosa del genere a generare ulteriori immobili a JSON:

<%= @user.attributes.merge(:avatar => image_path(@user.avatar)).to_json %> 
+7

Dovrebbe essere '<% = raw (@ user.to_json)%>' per evitare l'escape dell'HTML. Quello che faccio è che mi fido di to_json finché mi dà quello che voglio, ma quando voglio fare qualcos'altro lo metto a modello con quello che è solitamente un '{: blah => @ user.the_blah} .to_json'. – clacke

27

Rabl è probabilmente la soluzione più bella per questo che ho visto, se siete alla ricerca di un'alternativa più pulita per Sintassi ERb json_builder e argonaut, che sono altre soluzioni, sembrano entrambi un po 'obsoleti e non funzionano con Rails 3.1 senza alcune patch.

RABL è disponibile tramite una gemma o controlla il repository GitHub; buoni esempi troppo

https://github.com/nesquena/rabl

21

solo per aggiornare questa risposta per il bene degli altri che capita di finire in questa pagina.

In Rails 3, è sufficiente creare un file allo views/users/show.json.erb. L'oggetto @user sarà disponibile per la vista (proprio come sarebbe per l'html). Non hai nemmeno più bisogno di to_json.

In sintesi, si tratta solo

# users contoller 
def show 
    @user = User.find(params[:id]) 
    respond_to do |format| 
    format.html 
    format.json 
    end 
end 

e

/* views/users/show.json.erb */ 
{ 
    "name" : "<%= @user.name %>" 
} 
+1

Ho risposto a questo 1.5 anni fa. Oggi uso solo respond_with ogni volta che ho bisogno di JSON, ad es. 'answer_with @user, solo: [: name]'. Fare riferimento a questo [tutorial] (http://bendyworks.com/geekville/tutorials/2012/6/respond-with-an-explanation) per ulteriori informazioni. –

+1

Solo per aggiungere a questa risposta, questo è in realtà pericoloso per due motivi: consente l'iniezione dai dati dell'utente perché non sfugge a newline e backslash, e anche <% = html esegue l'escape dei dati così ad es. Sean O'Connor avrà il suo nome straziato a Sean O ' Connor. – d4n3

28

Come altri hanno detto hai bisogno di un'utenti/spettacolo.vista JSON, ma ci sono opzioni da considerare per il linguaggio di template ...

ERB

Opere fuori dalla scatola. Ottimo per HTML, ma scoprirai che è orribile per JSON.

RABL

buona soluzione. Devo aggiungere una dipendenza e imparare il suo DSL.

JSON Builder

Stessa cosa come Rabl: buona soluzione. Devo aggiungere una dipendenza e imparare il suo DSL.

Plain Rubino

Ruby è impressionante a generare JSON e non c'è niente di nuovo da imparare, come si può chiamare to_json su un hash o di un oggetto AR. È sufficiente registrare l'estensione .RB per i modelli (in un inizializzatore):

ActionView::Template.register_template_handler(:rb, :source.to_proc) 

quindi creare la vista degli utenti/show.json.rb:

@user.to_json 

Per maggiori informazioni su questo approccio vedere http://railscasts.com/episodes/379-template-handlers

+7

Nota che in rails 4, il gestore di template .ruby è registrato per impostazione predefinita https://github.com/rails/rails/commit/de1060f4e02925c12004f2 in modo da poter saltare la registrazione di .rb e denominare il file users/show.json.ruby. –

+1

Inoltre, per aggiornare ulteriormente, json_builder è stato sostituito da https://github.com/rails/jbuilder. –

Problemi correlati