Vistas diferentes de un Recurso (Different Views of a Resource)
Siguiendo un poco con esto de REST , me encontré durante el desarrollo con un problema que incluso consulté en los foros, pero nadie supo darme una respuesta.
La cuestión es simple: "un Recurso puede tener diferentes vistas, aún si hay solo un Representación disponible. Por ejemplo, un Recurso tiene una representación XML, pero diferentes clientes podrían ver una porción diferente del mismo XML."
En mi caso el problema se produce por un recurso llamado "producto"; así, la URL "/empresa/:empresa_id/productos" provee una lista de productos.
Este es el Controlador que maneja el Recurso:
class ProductosController < ApplicationController
# GET /empresa/:empresa_id/productos
def index
empresa = Empresa.find(params[:empresa_id])
render :partial => plantilla, :locals => { 'empresa' => empresa }
end
end
Como se puede ver, el método "index" se va al final a un partial que debe ser un archivo rhtml (o en mi caso un archivo haml), que a la larga será la representación HTML de una lista de productos.
A este URL del recurso se la hace una petición Ajax y el
HTML resultado es desplegado en un cuadrito (<div>) que se
despliega lentamente hacia abajo.
Hasta aquí todo normal.
El problema es que en otra parte del sistema se debe desplegar otro cuadrito con los productos, pero a diferencia del primero donde los productos se muestran como "links" (<a href...), en este los productos deben aparecer como "radio buttons" (<input type="radio"...).
Es claro que la última línea del método "index" (el render), solo me va a dirigir a una vista: ya sea la que muestra los productos como "links" o la que los muestra como "radio buttons".
Escribir otro controlador con un método "index" igual, pero que al final se valla a la otra vista no es para nada DRY.
¿Que hacer entonces?
Buscando como siempre encontré un propuesta de Hao He, en el artículo "Implementing REST Web Services: Best Practices and Guidelines ". Aunque como ahí mismo se advierte: es un estándar informal y podría NO ser RESTful en un sentido estricto.
La solución es: para obtener una vista diferente, un cliente puede poner un parámetro "view" en el query string del URI. Por ejemplo:
GET http://www.example.com/abc?view=radios
De manera que ahora modifiqué el controlador para que tenga en cuenta el parámetro enviado y así determine cual es la vista que el cliente necesita...
class ProductosController < ApplicationController
# GET /empresa/:empresa_id/productos
def index
empresa = Empresa.find(params[:empresa_id])
# mostrar la vista correcta de acuerdo al parametro enviado
plantilla = case params[:view]
when 'links' then 'productos_link'
when 'radios' then 'productos_radio'
else 'productos_link'
end
render :partial => plantilla, :locals => { 'empresa' => empresa }
end
end
Ahora, cuando se utilicen los helpers para generar la URL al recurso, debe tenerse en cuenta que puede recibir el parámetro "view". Ejemplos:
productos_path(:empresa_id => empresa.id, :view => 'links') productos_path(:empresa_id => empresa.id, :view => 'radios')
Saludos y como siempre espero sus comentarios.