Revista Informática

Ruby on Rails desde Cero: ActiveRecord parte 1

Publicado el 09 agosto 2013 por Codehero @codeheroblog

Las series de cursos Ruby on Rails en CodeHero buscan otorgarte los conocimientos necesarios, para que puedas desarrollar tus propias aplicaciones Web. Hasta este capítulo ya tenemos suficientes herramientas para comenzar con nuestra aplicación Web, abarcando temas básicos como instalación, estructura y funcionamiento de vistas dinámicas.

En este nuevo capítulo conoceremos mas sobre ‘ActiveRecord’ herramienta que nos proporciona Ruby para acceder a la base de datos sin ejecutar código SQL. En este curso les mostraremos sintaxis y ejemplos para agilizar el proceso de aprendizaje.


¿Qué es ActiveRecord?

Active Record es una clase para la administración y funcionamiento de los modelos. Esta clase proporciona la capa objeto-relacional que sigue rigurosamente el estándar ORM (Tablas en Clases, Registros en Objetos, y Campos en Atributos), facilita el entendimiento del código asociado a base de datos y encapsula la lógica específica haciéndola más fácil de usar para nosotros los programadores.

Ventajas del ActiveRecord

  • Manejo de entidades con objetos de Ruby.
  • Las acciones del CRUD (Insertar, leer, modificar y eliminar) están encapsuladas así que se reduce el código y se hace más fácil de comprender.
  • Código fácil de entender y mantener
  • Se reduce el uso de código SQL considerablemente lo que implica sierta independencia del manejador de base de datos que usamos.

Recuperando objeto único

ActiveRecord ofrece cinco maneras para obtener un objeto único que iremos demostrando una a una:

Find

Esta función nos permite obtener un objeto de la base de datos buscándolo por el identificador primario (primary key), un Ejemplo de esto seria:

# suponiendo existe el modelo Usuario
usuario = Usuario.find(10)

Suponiendo que ‘Usuario’ es el modelo que accede a base de datos, este ejemplo ejecuta el siguiente comando MySQL:

SELECT * FROM usuarios WHERE usuarios.id = 10 LIMIT 1

take

Esta función simplemente toma un objeto de la base de datos sin un orden específico. Veamos un ejemplo y la ejecución SQL que éste ejecuta:

usuario = Usuario.take

Este ejemplo ejecuta por detrás del código el siguiente comando SQL:

SELECT * FROM usuarios LIMIT 1

first y last

Estas útiles funciones nos dan el primer y último registro del objeto que estemos solicitando respectivamente. Veamos ejemplos de estas funciones y la equivalencia en sintaxis SQL:

# primer objeto de la tabla
usuario = Usuario.first

# ultimo Objeto de la lista
usuario = Usuario.last

El equivalente a la ejecución de estos ejemplos sería lo siguiente:

# primer objeto de la tabla
SELECT * FROM usuarios ORDER BY usuarios.id ASC LIMIT 1

# ultimo Objeto de la lista
SELECT * FROM usuarios ORDER BY usuarios.id DESC LIMIT 1

find_by

Esta última función recupera el primer registro que coincida con las características dadas, veamos un ejemplo con su equivalencia SQL para entender mejor:

Usuario.find_by nombre: 'Ricardo', apellido: 'Sampayo'

El equivalente comando SQL para este ejemplo es el siguiente:

SELECT * FROM usuarios WHERE nombre = 'Ricardo' and  apellido = 'Sampayo' LIMIT 1

Recuperación de varios objetos en lotes

Las funciones que mostraremos a continuación nos permite obtener listas de objetos.

all

Esta función como su nombre nos dice recupera todos los registros de una tabla retornando en un arreglos de objetos. Ejemplo y equivalencia en SQL:

usuarios = Usuario.all

Su equivalente sentencia SQL:

SELECT * FROM usuarios

find_each

El find_each método recupera un lote de registros y a continuación podemos manipular cada uno de los registros de forma individual. Este proceso ocurre hasta que haya procesado todos los objetos. Veamos unos ejemplos para comprender mejor esto:

# por defecto este primer ejemplo nos da los primeros 1000 registros 

Usuario.find_each do |user|
  . . . # se manipula cada uno de los objetos  
end

# En este otro ejemplo se extraen 5000 registros partiendo del usuario con identificador 15

Usuario.find_each(start: 15, batch_size: 5000) do |user|
  . . . # se manipula cada uno de los objetos  
end

Condiciones

ActiveRecord también nos provee métodos que nos permite especificar las condiciones para limitar los registros devueltos, lo que representa el ‘WHERE’ en sentencias SQL. Estas condiciones bien se pueden especificar de tres formas diferentes.

Primero mostraremos un ejemplo estableciendo como condición una cadena de caracteres (‘String’ es la que menos les recomiendo):

# todos los usuarios que se llamen Ricardo
usuarios = Usuario.where("nombre = 'Ricardo'")

#todos los usuarios que su nombre comience por Ri
usuarios = Usuario.where("nombre LIKE 'Ri%'")

Estos ejemplos ejecutan la siguiente sentencia SQL respectivamente:

# todos los usuarios que se llamen Ricardo
SELECT * FROM usuarios WHERE nombre = 'Ricardo';

#todos los usuarios que su nombre comience por Ri
SELECT * FROM usuarios WHERE nombre like 'Ri%' ;

A continuación mostraremos unos ejemplos más seguros para establecer condiciones de búsqueda, al igual que lo hemos hecho hasta ahora mostrando la sentencia SQL para ayudarnos a entrar en contexto:

# todos los usuarios que se llamen Ricardo
Usuario.where("nombre = ?", 'Ricardo')

# todos los usuarios mayores de 18 y menores de 50 años
Usuario.where("edad >= :init_edad AND edad <= :fin_edad", {init_edad: 18, fin_edad: 50})

Su equivalente SQL:

SELECT * FROM usuarios WHERE nombre = 'Ricardo';

SELECT * FROM usuarios WHERE edad >= 18 and edad <= 50;

Por último también podemos establecer nuestras condiciones de búsqueda como si fueran objetos (‘Hash’), veamos un ejemplo para explicar esto mejor:

# todos los usuarios que se llamen Ricardo
Usuario.where(nombre: 'Ricardo')

# Todos los usuarios que el nombre sea DIFERENTE de Ricardo
Usuario.where.not(nombre: 'Ricardo')

Su equivalente SQL:

SELECT * FROM usuarios WHERE nombre = 'Ricardo';

SELECT * FROM usuarios WHERE nombre != 'Ricardo';

Ordenando

Al igual que con las condiciones ActiveRecord también nos permite solicitar una lista registros ordenados por algunos de los campos (El equivalente al ORDER BY en SQL).

Por ejemplo ordenaremos en este caso los usuarios por fecha de última modificación (‘updated_at’ campos que se crean automáticamente para auditoria) de la siguiere manera:

ordenando por updated_al de forma ascendente 
Usuario.order("updated_at")

Ordenando por fecha de modificación decreciente y por nombre ascendente
Usuario.order("updated_at DESC , nombre ASC")

Su equivalente SQL:

SELECT * FROM usuarios ORDER BY usuarios.updated_at ASC;

SELECT * FROM usuarios ORDER BY usuarios.updated_at DESC , usuarios.nombre ASC;

Limit y Offset

Estas dos funciones nos permiten limitar la cantidad de elementos solicitados a la base de datos empezando desde un punto específico. un ejemplo de esto es lo siguiente:

solo 8 usuarios sin orden especifico
Usuario.limit(8)

solo 5 usuarios sin orden especifico comenzando desde la fila 31
Usuario.limit(5).offset(30)

Su equivalente SQL:

SELECT * FROM usuarios LIMIT 8 ;

SELECT * FROM usuarios LIMIT 5 OFFSET 30;

Group y Having

Al igual que con sintaxis SQL ActiveRecord nos permite hacer agrupaciones por algún campo de la base de datos y especificar condiciones a estos grupos veamos un ejemplo:

#Trae la fecha de actualización y el promedio de la edad 
#agrupados por día y donde el promedio sea mayor a 18

Usuario.select(date(updated_at) as ordered_date, avg(edad) as edad_avg").group("date(updated_at)").having("avg(edad) > ?", 18)

Conclusión

En esta lección conocimos básicamente como hacer peticiones a la base de datos sin necesidad de utilizar sintaxis SQL, vimos las ventajas más importantes de ActiveRecord y algunos conceptos básico para entrar en materia para el próximo capítulo.

En nuestro próximo capítulo estaremos profundizando un poco más sobre ActiveRecord, ya que aún nos queda mucho de este tema.

No dude en hacernos saber sus dudas y comentarios en la sección de comentarios y además espero que te unas a nuestra comunidad y revises nuestros otros cursos.

¡Hasta el próximo capítulo!


Volver a la Portada de Logo Paperblog