Apuntes Rails: Controladores
Publicado el Lunes, 9 de abril de 2012Los controladores son el pegamento entre la lógica de negocios y las vistas en el patrón de diseño MVC - Model, View, Controller.
Cuando el ruteo de Rails determiná qué controlador va a usar para un pedido http, nuestro controlador se va a encargar de darle sentido a este pedido y devolver una salida correspondiente.
Cada controlador es una clase Ruby que hereda de la clase de Rails ApplicationController
.
Métodos y Acciones
El ruteo determina qué controlador y acción debe ejecutar. Rails crea una instancia del controlador y ejecuta el método con el mismo nombre de la acción correspondiente.
Parámetros
Desde el controlador podemos acceder a todos los parámetros enviados en el pedido HTTP. Los dos tipos de parámetros son:
- Query String Parameters - Los enviados a través de la URL (lo que está en la URL después del signo "?").
- Post Data - Información de un pedido POST HTTP, generalmente enviado desde un form html.
Ambos tipos de parámetros están disponibles a través del hash params
.
El hash params puede contener Arrays y Hashes:
GET /clients?ids[]=1&ids[]=2&ids[]=3
> params[:id] = ["1", "2", "3"]
Hash
<form method="post"> <input name="client[name]" type="text" value="Acme"> <input name="client[phone]" type="text" value="8881234"> </form>
> params[:client] { "name" => "Acme", "phone" => "8881234" } |
El objeto params es de la clase HashWithIndifferentAccess
de Active Support, una clase cuya función es permitirnos escribir params[:key]
y params['key']
y obtener el mismo valor por ambas claves...
Parámetros JSON y XML
Rails convierte automáticamente los parámetros JSON y XML al hash params
.
Ejemplo JSON:
{ "company": { "name": "acme", "address": "Lo que sea" } } >params[:company] { :name => “acme”, “address” => “Lo que sea” } |
Omitir elemento raíz de JSON/XML:
En initializers - config.wrap.parameters = on
En controlador - wrap_parameters
Ruteando parámetros
En el hash params siempre encontramos las llaves :controller
y :action
pero deberíamos acceder a ellos con :controller_name
y :action_name
.
match 'clients/:status' => 'cliens#index', :foo => "bar"
GET /clients/active > params[:status] = "active" params[:foo] = "bar"
Sesiones
Las aplicaciones web tienen una sesión por cada usuario en la que se pueden guardar pequeñas cantidades de información que será persistida entre pedidos.
La sesión está disponible únicamente en el Controlador y la Vista. Se puede usar uno de varios mecanismos:
ActionDispatch::Session::cookieStore
- Guarda todo del lado del clienteActiveRecord::SessionStore
- Guarda la información en la base de datos usando ActiveRecordActionDispatch::Session::CacheStore
- Guarda la información en la cache de RailsActionDispatch::Session::MemCacheStore
- Guarda la información en un clúster memcache (implementación legacy, usar CacheStore en su lugar)
Todos los mecanismos de guardado de sesión usan una cookie para guardar un ID único para cada sesión (obligatorio usar una cookie, Rails no permite pasar el id de sesión a través de la URL).
Cookie Store
Guarda el id y la información en la cookie. Todos los otros mecanismos guardan el id y la información se obtiene con ese id buscando en el servidor. Es muy lviano, no requiere configuración. La información de la cookie está firmada pero no encriptada, Rails no la aceptará si ha sido editada.
Permite 4Kb de información. No debería guardar objetos complejos (como instancias de modelos).
ActionDispatch::Session::CacheStore
Para casos en los que la sesión de usuario no necesita guardar información crítica o no se necesita por períodos largos de tiempo. Usa la implementación de caché de tu aplicación para guardar sesiones.
Ventaja: Usar estructura actual de caché.
Desventaja: las sesiones serán efímeras, podrían desaparecer.
Archivo:
config/initializers/session_store.rb
- Cambiar el mecanismo de almacenamiento de sesión.
- Establecer la llave de sesión (nombre de la cookie)
- Pasar una llave de dominio para especificar el nombre de dominio para la cookie
Establecer una clave secreta para el firmado de la información de sesión - config/initializers/secret_token.rb
Accediendo a la sesión
En los Controladores se puede acceder a la sesión a través de metódos de instancia de sesión.
Los valores de la sesión se guardan usando pares clave valor como en un hash.
En el controlador:
def current_user @current_user ||= session[:current_user_id] && User.find_by_id(session[:current_user_id] end |
Guardando valores:
def create if user = User.authenticate(params[:username], params[:password]) session[:current_user_id] = user.id redirect_to root_url end end |
Para eliminar algo de la sesión, simplemente asignamos el valor nil a la clave. Para reiniciar toda la sesión, usamos el método reset_session
.
Flash
El flash es una parte especial de la sesión que desaparece con cada request. Ejemplo:
def destroy session[:user_id] = nil flash[:notice] = "Has cerrado sesión" redirect... |
También es posible asignar mensajes flash en redirecciones:
redirect_to root_url, :notice => "Has cerrado sesión correctamente" |
flash.keep
mantiene el valor para otro request.
flash.now
Accede a los valores en el mismo request.
Cookies
Las cookies (o galletitas) son pequeñas cantidades de información del lado del cliente que es persistida a través de pedidos y sesiones.
cookies
- Funciona como un hash:
cookies[:commenter_name] = @comment.name ... cookies.delete(:commenter_name) |
Observar que para borrar el valor de una sesión, se asignaba nil a la clave. En el caso de las cookies, se debe usar cookies.delete(:llave)
Conclusión
Voy a dejar por acá este primer post sobre Controladores en Rails. Si les interesa ir siguiendo este tema, a esta altura deberían entender el flujo de un request en un controlador, y por qué y cómo guardar información en la sesión o con cookies.
Hay más para ver sobre los controladores: filtros, los objetos request y response y algo de seguridad básica. Pero lo dejo para la próxima entrega de "Apuntes Rails" 🙂
3 comentarios en este post
Feed de comentarios-
Apuntes Rails: Migraciones | Picando Código |
3 septiembre. 2012 - 21:40
[…] y las armaba en forma de post. La segunda instancia en esa “serie” fue sobre los Controladores.Desde entonces no he usado mucho Rails, sí otros frameworks en Ruby como Sinatra y Cuba. Sin […]
Garusis 8 junio. 2013 - 12:52
Agradezco mucho tu post. Al fin he podido comprender correctamente el funcionamiento de las sesiones en general y me he dado cuenta que habia estado haciendo algo peligroso (Guardar elementos complejos en la sesion, usando como metodo el almacenamiento en cookies), asi que he tomado las respectivas medidas. Muchas gracias por la informacion.
L. Jacob 3 febrero. 2017 - 18:02
Curiosa forma de tomar apuntes. Le apunto que en el apartado de “Parámetros”, al final: “…es permitir escribit…”
¡Salud!