post thumbnail

Ruby on Rails desde Cero: Serializar Objetos (active_model_serializers)

Publicado Por: Ricardo Sampayo, El 18/10/2013


Detalles del Curso:

Dificultad: Intermedio

Duración: 30 min


Hemos habilitado un repo en GitHub para que puedas descargar el código de esta entrada:

Échale un vistazo aquí.

Las series de cursos Ruby on Rails en CodeHero buscan otorgarte los conocimientos necesarios, para que puedas desarrollar tus propias aplicaciones Web. En capítulos anteriores hemos aprendido muchas de las ventajas del framework, desde la instalación y la puesta en marcha de nuestras aplicaciones hasta el capítulo anterior, donde estuvimos estudiando ActiveModel y algunas de sus características.

En este nuevo capítulo estaremos estudiando la serialización de objetos, pero a diferencia de la introducción que vimos en el capítulo anterior en ésta estaremos haciendo uso de una gema llamada active_model_serializers


¿Qué hace la gema active_model_serializers?

Esta gema básicamente nos ayuda a serializar los objetos, al igual que como hicimos en el capítulo anterior usando ActiveModel::Serializers, pero con la diferencia que esta gema nos agrega una serie de funcionalidades que nos ayudan al manejo de estos objetos e incluso nos separan la lógica de serialización de nuestros controladores y modelos. Por lo general utilizamos esta gema para realizar APIs con formato JSON.


Demostración

Para la demostración de esta maravillosa gema veremos desde su instalación hasta la implementación, en algunos ejemplos sencillos, que podrás desarrollar fácilmente tu aplicación.

Instalación

Hasta este momento no hemos visto ni instalado ninguna gema en nuestra aplicación, ya es hora de hacerlo y como todo en Ruby on Rails te daras cuenta de lo fácil que resulta.

Básicamente la instalación de esta gema, en Ruby on Rails y en nuestra aplicación, sigue dos sencillos pasos. Primero agregamos en el archivo Gemlife nuestra gema de la siguiente manera:

gem "active_model_serializers"

Luego, nos vamos a nuestra consola o terminal y nos dirigimos hasta el directorio donde está el proyecto. Entramos dentro de la carpeta del proyecto y ejecutamos la famosa línea de código para instalar las gemas:

$ bundle install

Una vez realizados estos dos sencillos pasos ya nuestra aplicación está lista para hacer uso de nuestra gema serializadora.

¿Cómo creamos el serializador?

Para crear el serializador sólo basta con ejecutar un línea de comando en nuestra consola o terminal. Si queremos crear un modelo desde cero y ya estamos seguros que vamos a necesitar serializar los objetos, porque queremos hacer un API o simplemente queremos mostrarlo en un formato de uso común (JSON), utilizamos el siguiente comando:

$ rails g resource nombre_modelo atributo1:string atributo2:string

o

$ rails generate resource nombre_modelo atributo1:string atributo2:string

Como ven este comando nos crea los mismos archivos que cuando creamos un modelo, sólo que adicionalmente en la carpeta app nos agrega una nueva carpeta llamada serializers y a ésta un archivo Ruby donde desarrollamos la lógica para serializar.

También es posible crear un serializador a un objeto ya existente en nuestra aplicación de la siguiente manera:

$ rails g serializer nombre_modelo

o

$ rails generate serializer nombre_modelo

Este comando sólo nos crea la clase en Ruby, donde desarrollamos la lógica para serializar el objeto que indicamos.

¿Cómo usar el serializador?

Una vez que creamos nuestro serializador nos damos cuenta que tenemos unos archivos Ruby nuevos dentro de la carpeta Serializer que se debió haber creado. Estos archivos deben tener algo como esto:

class UsuariosSerializer < ActiveModel::Serializer
  attributes :id, :nombre, :apellido, :nacimiento, :sexo
end

Como ven es una simple clase que extiende de ActiveModel::Serializer con los atributos del modelo que en nuestro caso es Usuario.

Probablemente cuando creamos el serializador con la segunda opción de este tutorial, debamos agregar los atributos del modelo a mano (Por defecto sólo se crea con el id)

Una vez revisada y modificada la clase serializadora del modelo simplemente nos vamos a nuestro controlador y creamos un método (Recuerda agregar la ruta al archivo routes.rb). Por ejemplo:

class Usuario < ApplicationController
  def serializador
    @ejemplo1 = Usuario.all
    render json: @ejemplo1
  end
end

Listo!, con este comando ya tenemos a todos los usuarios impresos en formato JSON en nuestra aplicación.

{
  "nombreControlador": [
    {
      "id": 6,
      "nombre": "Ramses",
      "apellido": "Velasquez",
      "nacimiento": "1968-05-09",
      "sexo": "m"
    },
    {
      "id": 7,
      "nombre": "Perez",
      "apellido": "Juana",
      "nacimiento": "1996-05-09",
      "sexo": "f"
    }
  ]
}

¿Cómo cambiar la estructura del JSON?

Probablemente necesitemos ocultar algunos atributos de nuestro modelo, cambiar el formato del algunos atributos e incluso agregar funciones que puedan cambiar la estructura de nuestro modelo original. El uso de funciones, el manejar la lógica de serialización completamente separada de nuestra aplicación y poder definir nuestros propios atributos, es lo que hace verdaderamente útil esta gema.

Imaginemos que necesitamos a los usuarios, pero en este caso particular sólo nos hace falta el nombre completo y la fecha de nacimiento de cada uno de los usuarios. Debemos desarrollar el serializador de la siguiente forma:

class UsuarioSerializer < ActiveModel::Serializer
  attributes :nacimiento, {full_name: :full_name}

  def full_name
    "#{object.nombre} #{object.apellido}"
  end
end

Como ven en el ejemplo, desarrollamos una función llamada full_name donde concatenamos el nombre, ya que, para nuestro uso interno usamos el nombre por separado. Por último, para mostrar los atributos que queremos simplemente los sacamos o agregamos a nuestra lista de atributos.

Si deseáramos agregarle información extra a nuestra salida en formato JSON pudiéramos agregarlo directamente en nuestro controlador con la etiqueta meta. Veamos el siguiente ejemplo y la salida que genera:

def serializador
  @ejemplo1 = Usuario.all
  # meta_key es para cambiarle el nombre a la etiqueta que estamos agregando
  render json: @ejemplo1 , meta: {total: 10}, meta_key: 'meta_object'
end

Para tener una salida parecida a la siguiente:

{
  "nombre_controlador": [
    {
      "nacimiento": "1988-05-09",
      "full_name": "Ricardo Sampayo"
    }
  ],
  "meta_object": {
    "total": 10
  }
}

Por último, para terminar con este punto, esta gema también nos ofrece la posibilidad de tener varios serializadores con estructuras diferentes para ser usados según sea el caso. Por ejemplo, el serializador que hemos utilizado hasta ahora sólo tiene fecha de nacimiento y el nombre completo, pero, pudiéramos necesitar otro serializador que provea toda la información del modelo sin necesidad de aplicarle cambios al serializador principal. Veamos en el siguiente ejemplo cómo podemos llamar a un serializador diferente.

def serializador
  @ejemplo1 = Usuario.first
  render json: @ejemplo1 , serializer: UsuarioCustomSerializer
end

En caso de que el objeto que vayamos a serializar sea un arreglo de objetos utilizamos el siguiente:

def serializador
  @ejemplo1 = Usuario.all
  render json: @ejemplo1 , each_serializer: UsuarioCustomSerializer
end

Conclusión

En esta lección hemos estudiado una nueva y muy útil gema para desarrollar en Ruby on Rails. Esta gema, aunque ofrece algunas funciones que ya nos ofrece el framework y estudiamos en el capítulo anterior ActiveModel, nos otorga más libertad al serializar nuestros objetos y aún más importante nos mantiene el código separado de la lógica de negocios manteniendo el código limpio, ordenado y eficiente.

Una vez más te recomiendo echarle un vistazo a la serie completa de Ruby desde cero, así como a las otras series de CodeHero, agradeciendo de antemano todas sus dudas y comentarios en la sección de comentarios.

¡Hasta el próximo capítulo!


¿Te ha gustado esta publicación?

Compártela:

Por Ricardo Sampayo

Conoce más sobre este autor aquí


comments powered by Disqus