ORMs - Active Record & Data Mapper
Tags: database, beginners, programming
Published: 2021-12-24 00:53:57

## ¿Cuál es la diferencia entre Active Record y Data Mapper?

Cuando trabajamos con datos en una aplicación, probablemente necesitemos un ORM (Object Relational Mapping). Un ORM es la capa entre la base de datos y nuestra aplicación. Al usar un ORM, la mayoría del trabajo de crear, actualizar, leer y eliminar de la base de datos es hecho por este ORM.

La mayoría de los frameworks actuales están preparados para trabajar con un ORM sin problemas. Por ejemplo, Laravel trabaja normalmente con [Eloquent](https://laravel.com/docs/8.x/eloquent).

Las dos más famosas implementaciones de ORMs son Active Record y Data Mapper. En este artículo vamos a explorar la diferencia entre estos dos patrones, cuales son los beneficios y desventajas de elegir uno u otro.

___

## ¿Qué es un ORM y por qué necesitamos uno?

Antes de comenzar a hablar acerca de las diferencias entre Active Record y Data Mapper, vamos a hablar un poco sobre qué es un ORM y cuál es su utilidad.

Como dijimos anteriormente, un ORM es la capa que existe entre la base de datos y nuestra aplicación. En POO, trabajamos con objetos como nuestro principal punto de referencia.

Por ejemplo, podríamos tener el siguiente objeto:

```ts
user = new User();
user.name = "Elodin";
```

Sin embargo, las bases de datos pueden almacenar valores como strings o integers. 

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fy7bs6qbvb78wu2wc2z8.png)

Un `User` podría tener varios posteos en nuestra aplicación. Para conseguirlos, podríamos hacer algo así:

```ts
posts = user.posts;
```

Sin embargo, en la base de datos, los posteos estarían almacenados en un tabla, así:

![Image description](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vmnanaw6kvzfa2245sk0.png)

 Cuando trabajamos con objetos en nuestra aplicación, trabajamos con objetos simples que almacenan todas sus propiedades y relaciones.

No obstante, estos datos son almacenados individualmente en las diferentes tablas de la base de datos.

Un ORM es esa capa "mágica" que transforma los datos en forma de objetos en datos relacionales que pueden ser guardados en la base de datos y viceversa.

___

## ¿Qué es el patrón Active Record?

Este patrón de ORMs es probablemente el más popular.

Un ejemplo de uso típico sería el siguiente:

```ts
user = new User();
user.name = "Elodin";
user.save();
```

En el ejemplo de arriba creamos un nuevo objeto `User`, configurando el `username` y luego guardando el objeto en la base de datos.

ORMs del estilo Active Record mapean un objeto con una fila de la base de datos. En el ejemplo anterior, estaríamos mapeando el objeto `User` a una fila en la tabla `users`.

Cuando abramos el archivo de modelo `User`, notaremos que no necesitamos especificar las propiedades del objeto o como se relaciona con la base de datos. Con este tipo de ORMs, el modelo es capaz de determinar las propiedades del modelo automáticamente tomando como referencia el esquema de la base de datos.

Uno de los beneficios de este estilo de ORMs es que podemos llamar al método `save()` en el objeto para actualizar la base de datos. Cada modelo hereda de un objeto base (del patrón Active Record) por lo que tenemos acceso a todos los métodos relacionados a la presistencia de datos. Esto hace que comenzar a trabajar con ORMs de estilo Active Record sea muy fácil ya que son muy intuitivos.  

___

## ¿Qué es el patrón Data Mapper?

La gran diferencia entre ambos patrones es que el Data Mapper separa completamente el dominio de nuestra aplicación y la capa de persistencia. Esto significa que ninguno de nuestros modelos (objetos) sabe nada acerca de la base de datos.

Cuando usamos el patrón Data Mapper nuestro código luciría algo así:

```ts
user = new User();
user.username = "Elodin";
```

Hasta ahora, no hay diferencias con el patrón Active Record.

No obstante, los objetos del modelo Data Mapper no son más que objetos que no tienen conocimiento alguno sobre la base de datos. Esto significa que no podemos llamar al método `save()` en el objeto a almacenar porque este método no existe en este objeto.

En cambio, necesitaremos usar un servicio completamente diferente, por ejemplo, llamado Entity Manager:

```ts
user = new User();
user.username = "Elodin";
EntityManager.persist(user);
```

El gran beneficio del patrón Data Mapper es que los objetos que utilizamos en el dominio de nuestra aplicación no necesitan conocer nada acerca de cómo están guardados en la base de datos. Esto significa que nuestros objetos serán más livianos ya que no deberán heredar el ORM completo, sino que también habrá un proceso más estricto y formal para interactuar con la base de datos debido a que no podremos llamar al método `save()` en cualquier lugar en nuestro código.

___

## Entonces, ¿cuáles son las diferencias entre Active Record y Data Mapper?

Ambos patrones tienen aspectos positivos y negativos, por supuesto. Como ocurre con casi todo lo demás en el ámbito de la programación, no hay uno que sea mejor que otro, sino que... depende.

Con todo esto en mente, puede haber dos formas de juzgar cuál patrón nos conviene más usar en nuestro caso.

___

### El tipo de aplicación que estemos construyendo

Generalmente y a grandes rasgos, existen dos tipos de aplicaciones: aquellas basadas en los métodos CRUD y las basadas en el propio dominio de la aplicación.

En una aplicación basada en los métodos CRUD típicamente estaremos creando, leyendo, actualizando y eliminando entidades. También, puede que tengamos relaciones entre nuestros modelos, pero sobre todo, no hay reglas estrictas respecto a cómo estas relaciones están dadas.

Cuando construimos una aplicación que está basada o pensada desde el lado de la base de datos, la solucíon más óptima es el patrón Active Record. Éste último, nos permitirá rápida y fácilmente levantar y correr nuestra aplicación.

Si por el contrario, nuestra aplicación es construida pensando en satisfacer las reglas y procedimientos de un negocio, el patrón Data Mapper puede que sea la mejor opción. Éste patrón hará cumplir ciertas restricciones de tratar con datos y su persistencia, y también nos permitirá encapsular esas reglas de negocio dentro de las entidades.

___

### La aplicación y el entorno en el que está siendo construida

Si estamos construyendo un MVP (Producto Mínimo Viable) para testear un nuevo mercado, puede que tenga más sentido usar el patrón Active Record. Al principio, generalmente no sabemos del todo cuales reglas del negocio serán más importantes, y nunca lo sabremos si nos obsesionamos con la arquitectura de nuestra aplicación.

Por otro lado, si la idea es trabajar en una aplicación para un negocio ya existente, puede que sea mejor idea usar un patrón Data Mapper. Un negocio existente ya tendrá reglas y procedimientos por medio de los cuales funciona. Si usáramos un patrón Active Record terminaríamos intentando forzar estas reglas del negocio para que se adapten a nuestra idea de una aplicación pensada desde el lado de la base de datos. El patrón Data Mapper nos permitirá encapsular las reglas de dominio del negocio permitiéndonos trabajar de manera intuitiva y clara.

___

## Nota

Este artículo ha sido maś que nada teoría sin muchos ejemplos prácticos. Para ver un tutorial práctico sobre las diferencias entre estos dos patrones, el siguiente enlace será de utilidad => [How We Code: ORMs and Anemic Domain Models](https://fideloper.com/how-we-code) by [Chris Fidao](https://twitter.com/fideloper).



Fuente: https://www.culttt.com/2014/06/18/whats-difference-active-record-data-mapper