Respond_to

Creo que ya todos hemos visto el ejemplo del API de rails sobre el
soporte de web-service

def list
@people = Person.find(:all)

respond_to do |wants|
  wants.html
  wants.xml { render :xml => @people.to_xml }
end

end

Mi pregunta es ‘que diablos es el respond_to’?, parece un bloque, y en
efecto lo es, pero también parece un case. Cómo puedo escribir construcciones
similares en mi código?

Mi pregunta se debe al comportamiento casi antojadizo del compilador de
Ruby

Por qué esto sirve?

respond_to do |accepts|
  accepts.html { redirect_to :action => :welcome }
  accepts.xml { render :template => 'shared/welcome' }
end

Pero esto dá un error de sintaxis !!!

respond_to do |accepts|
  accepts.html
    { redirect_to :action => :welcome }
  accepts.xml { render :template => 'shared/welcome' }
end

Noten que la única diferencia es el cambio de linea

Uso Rails 1.1.6

Gracias foro

On 1/8/07, Esteban [email protected] wrote:

Uso Rails 1.1.6

Gracias foro

respond_to es un método que está incluido en ActionController
(Peak Obsession)
y por lo tanto en tus controladores.

Las llaves de un bloque (y el “do” y creo que los parámetros) deben
empezar en la línea del método del que el bloque es parámetro.

En tu caso el “método” es “html” y por lo tanto la llave tiene que
estar en la línea que pone “html”.

Daniel R. Troitiño wrote:

Las llaves de un bloque (y el “do” y creo que los parámetros) deben
empezar en la línea del método del que el bloque es parámetro.

En tu caso el “método” es “html” y por lo tanto la llave tiene que
estar en la línea que pone “html”.

Bien por fin comprendo, me costó un poco pues el “syntax sugar” usado me
escondía el significado del código (me empalagó)

respond_to recibe un bloque como parámetro. Dentro del bloque la
variable ligada responde a los mensajes html, xml, js, etc (y puede
responder a más pero es necesario registrar antes esos nuevos tipos de
mensajes). Cada uno de estos mensajes o funciones (html, xml, etc)
recibe un bloque como parámetro y solo lo ejecuta si el mensaje evalúa a
true.

Algo que me confundió fue el AWDWR donde dice
"You can think of it being a bit like a case statement, but it has one
big difference: it ignores the order you list the options in, and
instead uses the order from the incoming request (because the client
gets to say which format it prefers). "

Cómo puede ser posible que ignore el orden y salte directamente a la
opción verdadera?

respond_to do |wants|
   wants.html
   wants.xml { render :xml => @people.to_xml }
   wants.js { do_something_else}
 end

A mi parecer esto funciona asi: si el tipo es xml, entonces primero se
evalúa wants.html que evalúa a false, entonces pasa a la siguente línea
(wants.xml) que evalúa a true entoces se ejecuta (yield) el bloque y
posteriormente salé del bloque del respond_to sin evaluar el want.js
(posiblemente usando una raise exception).

On 1/9/07, Esteban [email protected] wrote:

Algo que me confundió fue el AWDWR donde dice
"You can think of it being a bit like a case statement, but it has one big
difference: it ignores the order you list the options in, and instead uses
the order from the incoming request (because the client gets to say which
format it prefers). "

Cómo puede ser posible que ignore el orden y salte directamente a la opción
verdadera?

Hola Esteban!

En este momento estoy de vacaciones y no quiero empezar a indagar en
el código de Rails, por mi salud :slight_smile:

Pero se me ocurre algo así: primero se ejecuta el bloque de
respond_to, que incluye llamadas a “métodos” que especifican los
formatos aceptados. Todos estos formatos se guardan, supongamos, en un
Hash (aunque viendo rápidamente el código de la documentación -no lo
pude evitar- hay algo más complejo). En otras palabras, no es que en
controlador “va siguiendo” todos los llamados al objeto de la variable
“wants” (o “format”), sino que ejecuta todo el bloque completo y
recién luego puede saber todas los formatos que has declarado como
aceptables.

Suponiendo que las claves son los formatos, y los valores, el bloque a
ejecutar (de nuevo, esto es precario, pero vi que te interesaba
cómoimplementar algo así en tu código), entonces quedaría un Hash tipo:

formats[“xml”] =
formats[“html”] =

Entonces “no importa el orden”, porque se hace:

formats[formato_requerido_por_cliente].call

Espero que haya entendido tu inquietud y que haya servido :slight_smile:

Saludos!