Eloquent, el manejador de modelos en Laravel

Eloquent es un ORM integrado en Laravel que reconstruye los datos que se encuentran en la base de datos del lenguaje SQL a objetos PHP y viceversa, con el objetivo de crear un código portable para no tener que usar SQL dentro del código PHP.

¿Qué usa Eloquent? Utiliza un sistema de Modelos que reciben o envían la información a la base de datos. Los modelos usan convenciones para que Laravel tenga más fácil el trabajo y nos ahorre líneas de código:

  • El nombre del modelo se escribe en singular, a contraposición de las tablas en la base de datos que son en plurarl. Así si tenemos la tabla «cartas», nuestro modelo se llamará «carta».
  • Se utiliza notación UpperCamelCase.

En el [anterior módulo de migraciones], habíamos creado dos tablas para los contactos y los teléfonos. Por lo que es lógico que ahora se creen sus correspondientes modelos.

Para crear un modelo utilizaremos el comando make:model que requiere un nombre (que empiece por mayúscula) y si también no habíamos creado la migración anteriormente podemos agregar la opción –migration

php artisan make:model Contacto
php artisan make:model Telefono

Una vez ejecutados los comandos, los modelos se ubican en el directorio /app/NombreDelModelo.php siendo ahora clases que extienden de la clase Model.

Aunque estos modelos ya nos servirían para trabajar con ellos, conviene configurarles ciertos valores, como el nombre de la tabla a la que apuntarán o los campos que serán introducidos mediante la aplicación. Laravel ya asume datos como las claves primarias o los estampados de fechas:

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Contacto extends Model
{
  protected $table = 'contactos';
  protected $fillable = ['nombre', 'apellidos'];
}
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Telefono extends Model
{
  protected $table = 'telefonos';
  protected $fillable = ['telefono', 'tipo'];
}

Recoger datos

Eloquent cuenta con un gran número de métodos que nos ayudarán con el manejo de base de datos de forma mucho más intuitiva por lo que para recoger todos los datos de una tabla y mostrarlos sin ningún argumento se usa el método all():

$contactos = Contacto::all();

foreach ($contactos as $value) {
  echo $value->nombre . " " . $value->apellidos . "<br>";
}

No se ve ninguna consulta SQL aquí pero indirectamente, el modelo está ejecutando un «SELECT * FROM contactos», guardándolo en un objeto y al recorrerlo, se muestran sus valores asociativos. Pero si queremos buscar por el identificador, se usa el método find() al que le pasamos un identificador.

$contacto = Contacto::find($id);

echo $contacto->nombre . " " . $contacto->apellidos;

Incluso podemos agregar condiciones adicionales que nos ayude a filtrar más aún las consultas:

<?php
use \App\Contacto;

Route::get('/contactos/all', function(){
  $contactos = Contacto::where('apellidos', 'Emmerich')
                ->orderBy('nombre', 'asc')
                ->take(10)
                ->get();
  foreach($contactos as $value){
    echo $value->nombre . " " . $value->apellidos;
  }
});

Insertar datos

Para crear un nuevo registro en la base de datos, primero se instancia el modelo, se establecen los atributos y se guarda con el método save:

$contacto = new Contacto;
  
$contacto->nombre = "Pedro";
$contacto->apellidos = "Jiménez";

$contacto->save();

Actualizar datos

Si se quiere actualizar los datos de la base de datos, funciona exáctamente igual que si queremos guardarlo, solo que primero debemos identificar el elemento que se va a modificar, poner los datos nuevos y guardarlo con save

$contacto = Contacto::find($id);

$contacto->nombre = "Heracles";

$contacto->save();

Borrar datos

Una vez que se encuentra el elemento que se va a borrar, se usa el método delete que elimina el registro de la base de datos

$contacto = Contacto::find($id);

$contacto->delete();

Como conclusión, Eloquent es sencillo de implementar pero es importante recordar que si vamos a usar modelos debemos incluirlos con espacios de nombres. De nada sirve ejecutar consultas mediantes los modelos sino se han incluido, nos lanzaría error.

Relaciones entre modelos

Si partimos de la base de que hemos creado una base de datos con sus relaciones bien formadas (es que hemos hecho bien las migraciones), Eloquent nos permite crear relaciones entre modelos, facilitándonos aún más si cabe, su uso para lanzar consultas.

En un ejemplo, cuento con esta migración de crear la tabla teléfonos que junto con otra de contactos, he compuesto la estructura de la base de datos en mi sistema:

Schema::create('telefonos', function (Blueprint $table) {
  $table->increments('id');
  $table->string('telefono');
  $table->integer('id_contacto')->unsigned();
  $table->foreign('id_contacto')->references('id')->on('contactos');
  $table->timestamps();
});

La lógica de estos modelos es: un teléfono solo puede pertenecer a un contacto mientras que un contacto puede tener varios teléfonos.

Relación one to one

Es el tipo de relación más básica en Eloquent. Por ejemplo, un coche solo tiene una matrícula. El método hasOne recibe el modelo como argumento:

class Coche extends Model
{
	public function matricula()
	{
	    return $this->hasOne('App\Matricula');
	}
}

El modo inverso sería que una Matrícula pertenece a un solo coche. En el modelo de la Matrícula deberíamos poner el método belongsTo pasándole el modelo contrario para cerrar la relación:

class Matricula extends Model
{
  public function coche()
  {
    return $this->belongsTo('App\Coche');
  }
}

Nota importante: Eloquent determina la clave foránea de la tabla padre por el nombre _id. Si en nuestro caso no tenemos nombrada así la foránea o queremos apuntar hacia otro campo del modelo, debemos pasar como segundo argumento la clave foránea correcta, por ejemplo:

public function contacto(){
  return $this->belongsTo('App\Contacto', 'id_contacto');
}
Relación one to many

Suponiendo una relación de uno a muchos como pueden ser un post que tenga infinitos comentarios, Eloquent nos facilita el método hasMany, y como en la relación uno-uno, se sigue usando el método belongsTo para nuestro modelo inverso:

class Post extends Model
{
  public function comments()
  {
    return $this->hasMany('App\Comment');
  }
}
Relación many to many

Aunque en SQL la relación entre muchos siempre desemboca en una nueva tabla, esto sigue siendo así en las migraciones, pero en Eloquent tan solo debemos usar el método belongsToMany para ambos modelos.

De esta manera, jugar con los modelos y recibir datos de ellos es mucho más dinámico y sencillo que no hacer tediosas consultas con subconsultas o JOINs que nos estropean el código.

Deja un comentario