Rails responde con: ¿ cómo funciona?


He estado leyendo aquí y allá sobre lo genial que es el método respond_with en Rails 3. Pero ni siquiera puedo encontrar una referencia a ella en las API de Rails o buscando el origen. ¿Puede alguien explicarme cómo funciona (qué opciones puedes usar, etc.) o indicarme el lugar donde realmente está implementado para que pueda leer el código por mi cuenta?

Author: Amelia, 2011-05-25

1 answers

Actualización para Rails 4.2 +

#respond_with y ::respond_to (n. b. class method) are no longer a part of Rails. Se migraron a la gema de terceros responders a partir de Rails 4.2 ( notas de la versión / commit con fecha de agosto de 2014). Si bien los respondedores no están incluidos en Rails de forma predeterminada, es una dependencia de Devise, y por lo tanto está disponible en muchas aplicaciones Rails.

El #respond_to método de instancia, sin embargo, es todavía una parte de Rails (5. 2rc1 al momento de escribir este artículo).

La documentación oficial de Rails API para ActionController::MimeResponds explica cómo funciona #respond_to. Los comentarios de la documentación original de Rails Guides para #respond_with y ::respond_to todavía se pueden encontrar en el código fuente de la gema de respuesta .


Respuesta original

El código para los respondedores se basa en una clase y un módulo. MimeResponds que se incluye en ActionController:: Base , la clase su ApplicationController hereda de. Luego está ActionController::Responder que proporciona el comportamiento predeterminado cuando se usa respond_with.


De forma predeterminada, el único comportamiento que proporciona rails en la respuesta es un intento implícito de representar una plantilla con un nombre que coincida con la acción. Cualquier cosa más allá de eso requiere más instrucciones dentro de la acción, o una llamada personalizada respond_to con un bloque para manejar múltiples respuestas de formato.

Como la mayoría de los controladores utilizan un patrón bastante común de personalización, los respondedores proporcionan un nivel adicional de abstracción al introducir más comportamiento predeterminado. Acciones de lectura que llaman a to_xml / to_json para formatos específicos, y acciones de mutador que proporcionan lo mismo, así como redirecciones para acciones de mutador exitosas.


Hay algunas oportunidades para personalizar cómo se comportan los respondedores, desde ajustes sutiles hasta anular o extender completamente el comportamiento.

Nivel de clase: respond_to

Aquí se especifican los formatos que el Respondedor debe manejar. Los formatos se pueden personalizar en cuanto a qué acciones se aplicarán. Cada formato se puede especificar con llamadas separadas, lo que permite una personalización completa de las acciones para cada formato.

# Responds to html and json on all actions
respond_to :html, :json

# Responds to html and json on index and show actions only.
respond_to :html, :json, :only => [:index,:show]

# Responds to html for everything except show, and json only for index, create and update
respond_to :html, :except => [:show]
respond_to :json, :only => [:index, :create, :update]

Nivel de clase: responder

Este es un atributo de clase que contiene al respondedor. Esto puede ser cualquier cosa que responda a la llamada, lo que significa que puede usar un proc/lambda o una clase que responda a la llamada. Otra alternativa es mezclar uno o módulos a los existentes respondedor para sobrecargar los métodos existentes, aumentando el comportamiento predeterminado.

class SomeController < ApplicationController
  respond_to :json

  self.responder = proc do |controller, resources, options|
    resource = resources.last
    request = controller.request
    if request.get?
      controller.render json: resource
    elsif request.post? or request.put?
      if resource.errors.any?
        render json: {:status => 'failed', :errors => resource.errors}
      else
        render json: {:status => 'created', :object => resource}
      end
    end
  end
end

Si bien puede haber algunos casos de uso de borde interesantes, es más probable que extender o mezclar módulos en el respondedor predeterminado sean patrones más comunes. En cualquier caso, las opciones que son relevantes son los recursos y las opciones, ya que se pasan desde el desde respond_with.

Nivel de instancia: respond_with

Las opciones aquí son las que se pasarían a render o redirect_to en su controlador, pero solo se incluyen para escenarios de éxito. Para las acciones GET estas serían las llamadas render, para otras acciones estas serían las opciones para redirect. Probablemente la más útil de ellas es la opción :location, que se puede usar para anular esa ruta de redirección en caso de que los argumentos para respond_with no sean suficientes para construir la URL correcta.

# These two are essentially equal
respond_with(:admin, @user, @post)
respond_with(@post, :location => admin_user_post(@user, @post)

# Respond with a 201 instead of a 200 HTTP status code, and also
# redirect to the collection path instead of the resource path
respond_with(@post, :status => :created, :location => posts_path)

# Note that if you want to pass a URL with a query string
# then the location option would be needed.
# /users?scope=active
respond_with(@user, :location => users_path(:scope => 'active'))

Como alternativa, la gema responders no solo proporciona algunos módulos para sobrescribir algunos de los comportamientos predeterminados. Reemplaza el respondedor predeterminado con una clase anónima que extiende el respondedor predeterminado y proporciona un método de nivel de clase para mezclar módulos personalizados con esta clase. El más útil aquí es el respondedor de flash, que proporciona un conjunto predeterminado de flashes, delegando la personalización al sistema I18n, config/locales/en.yml por defecto.

Algunos ejemplos de respondedores personalizados que he usado en proyectos anteriores incluyen un respondedor que decoró automáticamente mis recursos, y proporcionó un conjunto predeterminado de títulos de página con una interfaz para personalizar o anular fácilmente el título de la página.

 110
Author: Cluster,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-08 11:35:48