
¿Qué es Eloquent ORM?
Eloquent ORM se distribuye con el framework Laravel para trabajar con la base de datos de forma sencilla y sin complicaciones. Algunas de las funciones que le han dado fama son el soft delete, los timestamps, la implementación de ActiveRecord, la gestión de varias bases de datos, el eager loading, los observers de modelo, los eventos de modelo y muchas más. Las relaciones de Eloquent son métodos de las clases de modelo. Definidas como métodos, son potentes query builders: puedes encadenar llamadas y construir consultas muy expresivas.
¿Cómo funciona Eloquent ORM?
Eloquent ORM es conocido por su implementación de Active Record para trabajar con bases de datos. Active Record es un patrón arquitectónico en el que cada modelo de la arquitectura MVC corresponde a una tabla de la base de datos. Con Eloquent creas relaciones entre tus datos y trabajas con un modelo orientado a objetos sin esfuerzo. Escribir consultas SQL a mano es tedioso y lento, Eloquent te permite hacer las operaciones habituales sin largas sentencias SQL. Los modelos han vuelto triviales la inserción, la actualización, el borrado y la sincronización entre varias bases de datos. Solo tienes que definir las tablas y la relación entre ellas, y ya está.
Empezar con Eloquent
Laravel incluye una interfaz de línea de comandos integrada, la consola Artisan. Está construida sobre el componente Console de Symfony y facilita el trabajo desde la terminal durante la fase de desarrollo.
Antes de seguir, configura la conexión a la base de datos en el archivo config/database.php.
Antes de usar el modelo Eloquent, comprueba que tienes Laravel instalado. Si todavía no lo tienes, puedes descargarlo desde getcomposer.org
Para ver la lista de comandos disponibles en Artisan, escribe lo siguiente:
php artisan listVerás en pantalla todos los comandos con una breve descripción. Si necesitas ayuda sobre alguno, basta con escribirlo precedido de «help». Por ejemplo:
php artisan help migrateCrear modelos Eloquent
Antes de nada tienes que crear un modelo en la base de datos. Los modelos te ayudan con el seeding, las migraciones y demás, son ellos los que hablan con la base de datos. También te permiten consultarla y poblarla con datos. El modelo se guarda normalmente en App\Models por claridad y para mantener el código bien documentado. Nosotros preferimos esa práctica, pero la elección es tuya: la única condición es que la clase se cargue automáticamente según tu archivo composer.json. Todos los modelos Eloquent extienden la clase Illuminate\Database\Eloquent\Model. El comando básico para crear modelos es el comando `make:model` de Artisan:
php artisan make: model StudentLa sintaxis básica para definir un modelo es:
class User extends Model {}La migración de la base de datos también se puede generar al crear el modelo: basta con añadir `-m` o `-migration` al comando anterior.
php artisan make:model Student--migration
php artisan make:model Flight -mLos seeders, las factories, los controladores y otros tipos de clase se generan pasando los parámetros adecuados al comando `make:model` de Artisan. Aquí tienes algunos ejemplos:
php artisan make:model Flight --factory
php artisan make:model Flight -f
php artisan make:model Flight --seed
php artisan make:model Flight -s
php artisan make:model Flight --controller
php artisan make:model Flight -cAdemás, estos parámetros se pueden combinar para crear varias clases de una sola vez.
php artisan make:model Flight -mfscAlgunas convenciones básicas de los modelos que conviene tener en mente:
- Nombre de la tabla: por convención, el nombre de la tabla es el nombre del modelo en plural y en minúsculas. Por ejemplo, si el modelo se llama Student, la tabla debería llamarse students. Si el nombre del modelo tiene varias palabras, se separan con guion bajo.
- Clave primaria: Eloquent asume que la clave primaria es el atributo id. Puedes cambiar ese comportamiento con `$primaryKey`.
- Timestamp: por defecto, `created_at` y `updated_at` los gestiona Eloquent automáticamente. Si no quieres esa gestión automática, pon `$timestamp` a false. Y si quieres personalizar el formato de fecha y hora, usa la propiedad `$dateFormat` de tu modelo.
Actualizar y eliminar elementos
Actualizar
Para actualizar un modelo tienes que recuperarlo, modificar el atributo que quieras cambiar y llamar al método save. El campo `updated_at` se actualiza solo, así que no hace falta tocarlo a mano.
$student = Student::find(1);
$student->email = ‘xyz@example.com';
$student>save();Las actualizaciones masivas también se pueden hacer sobre todos los modelos que coincidan con una consulta.
Eliminar un modelo existente
Para borrar un modelo basta con llamar al método delete:
$student = Student::find(1);
$student>delete();Borrado por clave:
Student::destroy(1);
Student::destroy([1, 2, 3]);
Student::destroy(1, 2, 3);También puedes borrar a partir de una consulta.
$affectedRows = Student::where('votes', '>', 100)->delete();Modelos relacionados
En cualquier base de datos puede haber modelos relacionados. Cuando dos o más modelos dependen unos de otros para su valor, se habla de modelos relacionados. Por ejemplo, si quieres añadir un comentario nuevo a un post, en lugar de rellenar el campo post_id a mano, puedes crearlo directamente desde el modelo padre
$comment = new Comment(['message' => 'A new comment.']);
$post = Post::find(1);
$comment = $post->comments()->save($comment);Modelos asociados
Estos modelos se actualizan con el método associate, que fija una clave foránea en el modelo. También puedes asociar modelos que tengan varias relaciones.
Eventos de modelo
Cada vez que un modelo pasa por una etapa de su ciclo de vida (guardado, actualización o borrado) se dispara un evento de modelo. Los eventos disponibles son saved, deleted, updating, deleting, updated, restoring y restored. Por ejemplo, al insertar un elemento nuevo se dispara creating/created, si el elemento ya existía, se dispara updating/updated.
Cancelar el guardado desde un evento
Si el evento devuelve false, la acción se cancela. Sirve con cualquier evento: borrado, actualización, creación o guardado.
Student::creating(function($student)
{
if ( ! $student>isValid()) return false;
});Cómo registrar listeners de eventos
Como en cualquier lenguaje, un evento necesita un service provider para registrarse. Aquí ocurre lo mismo: los listeners se registran en EventServiceProvider que es el sitio previsto para declarar los bindings de eventos de modelo.
Ejemplo:
public function boot(DispatcherContract $events)
{
parent::boot($events);
Student::creating(function($student)
{
//
});
}Observers de modelo
Los observers de modelo ayudan a gestionar los eventos de modelo. Una clase observer puede tener métodos que se corresponden con los distintos eventos.
class StudentObserver {
public function saving($model)
{
//
}
public function saved($model)
{
//
}
}Otra forma de registrar un observer es con el método observe
User::observe(new UserObserver);Generar URLs a partir de un modelo
Las URLs de modelo se construyen pasando el modelo al método route o action. Cuando le pasas un modelo, su clave primaria se inserta en la URI.
Route::get('student/{student}', 'StudentController@show');
action('StudentController@show', [$student]);Aquí se insertará en la URL el identificador del estudiante. Si prefieres usar otra propiedad en la URL generada, sobrescribe el método getRouteKey en tu modelo.
public function getRouteKey()
{
return $this->slug;
}Más funciones de Eloquent en Laravel
Convertir a array o a JSON
Cuando construyes una API el resultado suele ir en JSON, así que tienes que convertir tus relaciones a JSON o a array. Eloquent también cubre esa necesidad. Para convertir a array las relaciones de un modelo, tienes el método toArray().
$student = Student::with('roles')->first();
return $student->toArray();Para convertir a array una colección entera, puedes usar estos métodos:
return Student::find(1)->toJson();Veamos ahora cómo devolver un modelo desde una ruta. Cada vez que un modelo se convierte a cadena se convierte a JSON, así que puedes devolver objetos Eloquent directamente desde las rutas.
Route::get('student', function()
{
return Student::all();
});Algunos campos sensibles como `personal_id` o la contraseña tienen que quedar ocultos. Para eso hay que declarar `$hidden` en tu modelo,
Casting de atributos
Si quieres convertir el tipo de dato de un atributo, una opción es escribir un mutador para cada uno, lo que lleva tiempo y acaba generando bugs. La otra opción es aplicar un cast a ese atributo: basta con añadirlo a la propiedad casts de tu modelo. Los tipos de cast admitidos son integer, float, double, real, object, string, array.
Aquí tienes un ejemplo.
protected $casts = [
'is_student' => 'boolean',
];En este ejemplo, aunque is_student tenga otro tipo de dato en la base de datos, al leerlo lo recibirás como un booleano.
El cast a array resulta muy útil cuando trabajas con una columna que guarda JSON serializado. Serializar en JSON significa codificar un objeto en una cadena. Si una de tus columnas contiene JSON serializado, el cast a array lo convertirá automáticamente en un array de PHP al leerlo desde el modelo Eloquent.
protected $casts = [
'options' => 'array',
];Mutadores de fecha
Carbon es una extensión de la clase DateTime de PHP. Eloquent convierte created_at y updated_at en instancias de Carbon, que aporta un montón de métodos útiles sobre DateTime. Si no quieres esa conversión automática, personalizarla es sencillo: basta con sobrescribir el método getDates de tu modelo. Para desactivar por completo la conversión de fechas, devuelve un array vacío en el método `getDates` . Aquí tienes un ejemplo:
public function getDates()
{
return ['created_at'];
}Si una columna se trata como una fecha, tienes cuatro posibilidades: un timestamp UNIX, una cadena de fecha (Y-m-d), una fecha y hora, o una instancia de DateTime o de Carbon.
Accesores y mutadores
Igual que se leen y se escriben valores en cualquier lenguaje, los accesores y los mutadores permiten formatear los atributos de Eloquent antes de leerlos o de asignarlos en las instancias del modelo. La diferencia está en el sentido: los accesores sirven para recuperar los datos, mientras que los mutadores se encargan de modificarlos.
Para definir un accesor basta con declarar `getFooAttribute` en tu modelo, respetando el camelCase del nombre del método aunque la columna esté en minúsculas.
class User extends Model {
public function getFirstNameAttribute($value)
{
return ucfirst($value);
}
}Un mutador se define de la misma forma: usa `setFooAttribute` y, otra vez, respeta el camelCase.
class User extends Model {
public function setFirstNameAttribute($value)
{
$this->attributes['first_name'] = strtolower($value);
}
}Soft delete
El soft delete no borra la fila de la base de datos, sino que rellena un timestamp aparte. La columna `deleted_at` se añade al registro correspondiente. Para activarlo en tu modelo, aplícale el trait SoftDeletes.
use Illuminate\Database\Eloquent\SoftDeletes;
class User extends Model {
use SoftDeletes;
protected $dates = ['deleted_at'];
}softDeletes() sirve para añadir la columna deleted_at desde la migración. Una migración no es más que gestionar la base de datos en PHP en lugar de en SQL.
$table->softDeletes();En algunos casos querrás ver también los registros borrados en soft delete al lanzar una consulta. Para eso tienes withTrashed() en la consulta.
Si solo quieres ver los modelos borrados en soft delete, usa el método onlyTrashed() en la consulta.
$student = Student::onlyTrashed()->where('account_id', 1)->get();Después de tantas operaciones, si quieres devolver al estado activo un modelo borrado en soft delete, usa el método restore.
$student->restore();restore() también se puede usar directamente en la consulta.
Student::withTrashed()->where('account_id', 1)->restore();Y si después del soft delete quieres borrar el modelo definitivamente de la base de datos, usa el método forceDelete().
$student->posts()->forceDelete();Para comprobar si un modelo está borrado o no, tienes el método trashed().
if ($student->trashed())
{
//Todo
}Conclusión
Laravel es uno de los frameworks más conocidos de PHP, y Eloquent hace que comunicarse con la base de datos sea muy sencillo. En este artículo hemos repasado algunas de sus funciones más importantes. Hay muchas más, y puedes conocerlas aquí. Sigue el enlace y descubre todo lo que ofrece Eloquent.


