Rotaie: come funziona il respond_to block?


211

Sto esaminando la guida introduttiva a Rails e mi sono confuso con la sezione 6.7. Dopo aver generato uno scaffold trovo il seguente blocco generato automaticamente nel mio controller:

def index
  @posts = Post.all

  respond_to do |format|
    format.html  # index.html.erb
    format.json  { render :json => @posts }
  end
end

Mi piacerebbe capire come funziona il blocco response_to. Che tipo di variabile è il formato? I metodi .html e .json dell'oggetto format sono? La documentazione per

ActionController::MimeResponds::ClassMethods::respond_to

non risponde alla domanda.


Sarebbe bello se potessi collegarmi alla documentazione di ActionController :: MimeResponds :: ClassMethods :: respond_to ma api.rubyonrails.org non sembra gradire i collegamenti ipertestuali diretti ...
Cole,

respond_to accetta la fine della chiamata (ad es. blah.html, blah.json, ecc.) e corrisponde alla vista specificata. Altre risposte possono essere XML, CSV e molte altre a seconda dell'applicazione.
ScottJShea,

5
In che modo "corrisponde alla vista specificata?"
Cole,

Non credo che l'estensione (xml, html, ecc.) Sia mappata su una vista. Se scegli il rendering predefinito ( format.html- nessun argomento) userà le convenzioni (basate su URL e verbo HTTP) per scegliere una vista (che dovrebbe essere HTML). Il risponditore (formato) viene incaricato qui di eseguire il rendering degli URL che terminano con .json serializzando su json, anziché utilizzare viste e convenzioni.
Craig Celeste,

Risposte:


189

Sono nuovo di Ruby e mi sono bloccato su questo stesso codice. Le parti a cui sono stato appeso erano un po 'più fondamentali di alcune delle risposte che ho trovato qui. Questo può o meno aiutare qualcuno.

  • respond_to è un metodo sulla superclasse ActionController .
  • prende un blocco, che è come un delegato. Il blocco è di dofino a end, con|format| come argomento per il blocco.
  • respond_to esegue il blocco, passando un risponditore formatnell'argomento.

http://api.rubyonrails.org/v4.1/classes/ActionController/Responder.html

  • Il Respondernon contiene un metodo per.html o .json, ma chiamare questi metodi in ogni modo! Questa parte mi ha gettato per un giro.
  • Ruby ha una funzione chiamata method_missing. Se chiami un metodo che non esiste (come jsono html), Ruby chiama ilmethod_missing invece metodo.

http://ruby-metaprogramming.rubylearning.com/html/ruby_metaprogramming_2.html

  • La Responderclasse usa la sua method_missingcome una specie di registrazione. Quando chiamiamo "json", gli stiamo dicendo di rispondere alle richieste con l'estensione .json serializzando su json. Dobbiamo chiamarehtml senza argomenti per dirgli di gestire le richieste .html nel modo predefinito (usando convenzioni e viste).

Potrebbe essere scritto in questo modo (usando lo pseudocodice simile a JS):

// get an instance to a responder from the base class
var format = get_responder()

// register html to render in the default way
// (by way of the views and conventions)
format.register('html')

// register json as well. the argument to .json is the second
// argument to method_missing ('json' is the first), which contains
// optional ways to configure the response. In this case, serialize as json.
format.register('json', renderOptions)

Questa parte mi ha confuso. Lo trovo ancora poco intuitivo. Ruby sembra usare questa tecnica un po '. L'intera classe ( responder) diventa l'implementazione del metodo. Per sfruttaremethod_missing , abbiamo bisogno di un'istanza della classe, quindi siamo obbligati a passare un callback in cui passano l'oggetto simile al metodo. Per qualcuno che ha codificato in linguaggi simili a C per 20 anni, questo è molto arretrato e poco intuitivo per me. Non è male! Ma è qualcosa che molte persone con quel tipo di background hanno bisogno di capovolgere, e penso che potrebbe essere ciò che l'OP stava cercando.

ps si noti che in RoR 4.2 è respond_tostato estratto nella gemma di responder .


Grazie Craig, quel link in realtà aveva anche un sacco di informazioni utili, non mi rendevo conto di quanto fosse possibile method_missing, considerando che puoi passare argomenti e un blocco!
Aditya MP

2
La migliore risposta per spiegare l'uso di method_missing () come meccanismo di registrazione nella classe Responder! Ero anche molto confuso con questo codice.
Alan Evangelista,

1
I generatori di scaffold di Rails 6 sembrano produrre codice respond_tonei controller, senza la gemma dei responder presente nel Gemfile. Forse la parte respond_todell'essere estratta nella gemma dei soccorritori è stata cambiata?
Qasim
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.