unknownformat respond_with respond_to rails method ruby-on-rails

ruby-on-rails - respond_with - respond_to rails 5



Rieles: ¿Cómo funciona respond_to block? (9)

¿Qué tipo de variable es el formato?

Desde un POV de java, el formato es una implementación de una interfaz anónima. Esta interfaz tiene un método nombrado para cada tipo mime. Cuando invocas uno de esos métodos (pasándole un bloque), si Rails siente que el usuario quiere ese tipo de contenido, invocará tu bloque.

El giro, por supuesto, es que este objeto de pegamento anónimo no implementa realmente una interfaz, atrapa las llamadas de método de forma dinámica y se resuelve si es el nombre de un tipo mime que conoce.

Personalmente, creo que se ve raro: el bloque que pasas se ejecuta . Tendría más sentido para mí pasar un hash de etiquetas y bloques de formato. Pero, así es como se hace en RoR, parece.

Revisé la guía de Primeros pasos con los rieles y me confundí con la sección 6.7. Después de generar un andamio, encuentro el siguiente bloque generado automáticamente en mi controlador:

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

Me gustaría entender cómo funciona realmente el bloque respond_to. ¿Qué tipo de variable es el formato? ¿Son los métodos .html y .json del objeto de formato? La documentation para ActionController::MimeResponds::ClassMethods::respond_to no responde la pregunta.


Me gustaría entender cómo funciona realmente el bloque respond_to. ¿Qué tipo de variable es el formato? ¿Son los métodos .html y .json del objeto de formato?

Para entender qué es el format , primero debe mirar la fuente de respond_to , pero rápidamente encontrará que lo que realmente necesita es el código para retrieve_response_from_mimes .

Desde aquí, verá que el bloque que se pasó a respond_to (en su código), en realidad se llama y se pasa con una instancia de Collector (a la que, dentro del bloque, se hace referencia como format ). El colector básicamente genera métodos (creo que al inicio de Rails) basados ​​en lo que mime type rails conoce.

Entonces, sí, .html y .json son métodos definidos (en tiempo de ejecución) en la clase Collector (también conocido como format ).


"Formato" es su tipo de respuesta. Podría ser json o html, por ejemplo. Es el formato de la salida que su visitante recibirá.


Este es un bloque de código Ruby que aprovecha el método de ayuda de Rails. Si aún no estás familiarizado con los bloques, los verás mucho en Ruby.

respond_to es un método auxiliar de Rails que se adjunta a la clase Controller (o más bien, a su súper clase). Se refiere a la respuesta que se enviará a la Vista (que va al navegador).

El bloque en su ejemplo es el formato de datos, pasando un parámetro de ''formato'' en el bloque, que se enviará desde el controlador a la vista cada vez que un navegador realice una solicitud de datos html o json.

Si está en su máquina local y tiene configurado su andamio de publicaciones, puede ir a http://localhost:3000/posts y verá todas sus publicaciones en formato html. Pero, si escribe esto: http://localhost:3000/posts.json , verá todas sus publicaciones en un objeto json enviado desde el servidor.

Esto es muy útil para hacer aplicaciones pesadas de javascript que necesitan pasar json desde el servidor. Si lo desea, puede crear fácilmente una api de json en el back-end de sus rieles y solo pasar una vista, como la vista de índice de su controlador Post. Luego, puede usar una biblioteca de javascript como Jquery o Backbone (o ambas) para manipular los datos y crear su propia interfaz. Estas se llaman UI asíncronas y se están volviendo muy populares (Gmail es una). Son muy rápidos y le brindan al usuario final una experiencia de escritorio más en la web. Por supuesto, esto es solo una ventaja de formatear sus datos.

La manera de escribir de Rails 3 sería esta:

class PostsController < ApplicationController # GET /posts # GET /posts.xml respond_to :html, :xml, :json def index @posts = Post.all respond_with(@posts) end # # All your other REST methods # end

Al colocar respond_to :html, :xml, :json en la parte superior de la clase, puede declarar todos los formatos que desea que el controlador envíe a sus vistas.

Luego, en el método del controlador, todo lo que tienes que hacer es responder_with (@whatever_object_you_have)

Simplemente simplifica su código un poco más de lo que Rails genera automáticamente.

Si quieres saber sobre el funcionamiento interno de este ...

Por lo que entiendo, Rails inspecciona los objetos para determinar cuál será el formato real. El valor de las variables de ''formato'' se basa en esta introspección. Los rieles pueden hacer mucho con un poco de información. Te sorprenderías de lo lejos que irá un simple @post o: post.

Por ejemplo, si tuviera un archivo parcial _user.html.erb que se parecía a esto:

_user.html.erb

<li> <%= link_to user.name, user %> </li>

Entonces, esto solo en mi vista de índice le permitiría a Rails saber que necesitaba encontrar los ''usuarios'' parciales e iterar a través de todos los objetos de ''usuarios'':

index.html.erb

<ul class="users"> <%= render @users %> </ul>

le dejaría saber a Rails que necesitaba encontrar el ''usuario'' parcial e iterar a través de todos los objetos de ''usuarios'':

Puede encontrar útil esta publicación de blog: http://archives.ryandaigle.com/articles/2009/8/6/what-s-new-in-edge-rails-cleaner-restful-controllers-w-respond_with

También puede leer la fuente: https://github.com/rails/rails


Esto es un poco anticuado, por Ryan Bigg hace un gran trabajo explicando esto aquí:

http://ryanbigg.com/2009/04/how-rails-works-2-mime-types-respond_to/

De hecho, podría ser un poco más detallado de lo que estabas buscando. Resulta que hay muchas cosas detrás de la escena, incluida la necesidad de comprender cómo se cargan los tipos MIME.


Hay una cosa más que debes tener en cuenta: MIME.

Si necesita utilizar un tipo MIME y no es compatible de forma predeterminada, puede registrar sus propios controladores en config / initializers / mime_types.rb:

Mime::Type.register "text/markdown", :markdown


La meta-programación detrás del registro de respondedores (ver la respuesta de Parched Squid) también te permite hacer cosas ingeniosas como esta:

def index @posts = Post.all respond_to do |format| format.html # index.html.erb format.json { render :json => @posts } format.csv { render :csv => @posts } format.js end end

La línea csv hará que se llame a_csv en cada publicación cuando visite /posts.csv. Esto facilita la exportación de datos como CSV (o cualquier otro formato) desde su sitio de rieles.

La línea js hará que se genere / ejecute un archivo javascript /posts.js (o /posts.js.coffee). Descubrí que es una forma liviana de crear un sitio habilitado para Ajax usando jQuery UI pop-ups.


Por lo que sé, respond_to es un método adjunto al ActionController, por lo que puede usarlo en todos los controladores, ya que todos se heredan del ActionController. Aquí está el método Rails respond_to:

def respond_to(&block) responder = Responder.new(self) block.call(responder) responder.respond end

Le estás pasando un block , como muestro aquí:

respond_to <<**BEGINNING OF THE BLOCK**>> do |format| format.html format.xml { render :xml => @whatever } end <<**END OF THE BLOCK**>>

El formato | parte es el argumento que espera el bloque, por lo que dentro del método respond_to podemos usarlo. ¿Cómo?

Bueno, si observa que pasamos el bloque con un prefijo & en el método respond_to, y lo hacemos para tratar ese bloque como un Proc. Como el argumento tiene el ".xml", ".html", podemos usarlo como métodos para llamar.

Lo que básicamente hacemos en la clase respond_to es llamar a los métodos ".html, .xml, .json" a una instancia de una clase de respuesta.


Soy nuevo en Ruby y me quedé atascado en este mismo código. Las partes de las que me colgué eran un poco más fundamentales que algunas de las respuestas que encontré aquí. Esto puede o no puede ayudar a alguien.

  • respond_to es un método en la superclase ActionController .
  • toma un bloque, que es como un delegado. El bloque es desde do hasta end , con |format| Como argumento al bloque.
  • respond_to ejecuta su bloque, pasando un Servicio de respuesta al argumento de format .

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

  • El Servicio de Responder NO contiene un método para .html o .json , ¡pero llamamos a estos métodos de todos modos! Esta parte me lanzó por un bucle.
  • Ruby tiene una característica llamada method_missing . Si llama a un método que no existe (como json o html ), Ruby llama al método method_missing lugar.

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

  • La clase Responder utiliza su method_missing como un tipo de registro. Cuando llamamos ''json'', le decimos que responda a las solicitudes con la extensión .json mediante la serialización de json. Necesitamos llamar a html sin argumentos para indicarle que maneje las solicitudes .html de manera predeterminada (usando convenciones y vistas).

Podría escribirse así (usando pseudocódigo similar 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)

Esta parte me confundió mucho. Todavía lo encuentro poco intuitivo. Ruby parece usar esta técnica bastante. La clase entera ( responder ) se convierte en la implementación del método. Para aprovechar method_missing , necesitamos una instancia de la clase, por lo que estamos obligados a pasar una devolución de llamada a la que pasan el objeto similar a un método. Para alguien que ha codificado en lenguajes tipo C durante 20 años, esto es muy atrasado y poco intuitivo para mí. ¡No es que sea malo! Pero es algo que mucha gente con ese tipo de antecedentes necesita entender, y creo que podría ser lo que buscaba el OP.

ps nota que en RoR 4.2 respond_to se extrajo en la gema responders .