Eloquent la capa de abstracción de la base de datos que utiliza Laravel.
Eloquent es un modelo objeto-Relacional ORM que se implementa en laravel. De esta forma se va a establecer una clase (el modelo) nos va a permitir trabajar de forma sencilla y muy productiva con una base de datos. El modelo (la clase) se va a relacionar con una tabla en la BD. Relaciones entre tablas/modelos
El ORM Eloquent nos pone fácil para tratar las relaciones entre tablas. Basta añadir algunos métodos a los modelos implicados. Vamos a ver únicamente las relaciones 1:N Para relaciones 1:1 y N:M ver la documentación Vamos a verlo con el ejemplo entre usuarios y roles: un Role puede tener varios Users y un User pertenece a un Role. Crear modelo Role (y migración, seeder y controlador) -cr añade el controlador (c) tipo resource (r) php artisan make:model Role -mscr
public function up()
{
Schema::create('roles', function (Blueprint $table) {
$table->id();
$table->string('name')->unique();
$table->timestamps();
});
}
public function down()
{
Schema::dropIfExists('roles');
}
Modificación de la tabla users. Es habitual tener que modificar tablas que ya existen. Para eso usamos migraciones un poco diferentes: public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->unsignedBigInteger('role_id')->default(1);
$table->foreign('role_id')->references('id')->on('roles');
});
}
public function down()
{
//las fk se mombran así: tabla_columna_foreign
//esto se usa para eliminar la clave en el down
Schema::table('users', function (Blueprint $table) {
$table->dropForeign('users_role_id_foreign');
$table->dropColumn('role_id');
});
}
Creamos o modificamos el RoleSeeder y el UserSeeder: public function run()
{
//con DB
\DB::table('roles')->insert([
'id' => '1',
'name' => 'registrado'
]);
\DB::table('roles')->insert([
'id' => '2',
'name' => 'usuario'
]);
\DB::table('roles')->insert([
'id' => '3',
'name' => 'administrador'
]);
}
public function run()
{
//con DB
\DB::table('users')->insert([
'id' => '1',
'name' => 'registrado',
'email' => 'registrado@dws.es',
'password' => bcrypt('secret')
]);
\DB::table('users')->insert([
'id' => '2',
'name' => 'usuario',
'email' => 'usuario@dws.es',
'password' => bcrypt('secret'),
'role_id' => 2
]);
\DB::table('users')->insert([
'id' => '3',
'name' => 'admin',
'email' => 'admin@dws.es',
'password' => bcrypt('secret'),
'role_id' => 3
]);
}
No debemos olvidar actualizar el DatabaseSeeder: public function run()
{
$this->call(RoleSeeder::class);
$this->call(UserSeeder::class);
$this->call(StudiesSeeder::class);
// \App\Models\User::factory(10)->create();
}
Por fín los modelos: Vamos a tratar una relación 1:N Un Role tiene muchos Users asociados. La clase Role debe incluir el siguiente método: class Role extends Model
{
// resto del código
//el método users nos devolverá una colección de usuarios
//el nombre es significativo
public function users()
{
return $this->hasMany(User::class);
}
}
Un User pertenece a un Role. La clase Role debe incluir el siguiente método: class User extends Authenticatable
{
// resto del código
//el método role nos devolverá un objeto role
// el nombre también es significativo
public function role()
{
return $this->belongsTo(Role::class);
}
}
Ahora podemos usarla en nuestras vistas. Por ejemplo en "user/index.blade.php" @foreach($users as $user)
<tr>
<td>{{ $user->name }}</td>
<td>{{ $user->role->name }}</td>
</tr>
@endforeach
O en "role/show.blade.php" {{ $role->name }}
<h2>Lista de usuarios</h2>
@foreach ($role->users as $user)
<li>{{$user->name}}</li>
@endforeach
Eloquent con más de un atributo en una clave primaria
En Eloquent, la clave primaria se usa para identificar únicamente cada registro en una tabla. Por defecto, Eloquent asume que la clave primaria de una tabla es una columna llamada id. Sin embargo, en caso de que tu tabla tenga más de una clave primaria, puedes especificar qué columnas deben ser utilizadas como clave primaria en tu modelo.
Hay varias formas de especificar múltiples claves primarias en Eloquent.
Una forma es indicando en el Modelo Eloquent con la propiedad $primaryKey, se puede especificar una o varias columnas que deben ser utilizadas como clave primaria:
class TuModelo extends Model { protected $primaryKey = ['columna1', 'columna2']; ... }
Otra forma es agregando en el modelo una propiedad $incrementing como false para desactivar el tratamiento de clave primaria como autoincrementable:
class TuModelo extends Model { public $incrementing = false;
Es importante que tengas en cuenta que las claves primarias compuestas no soportan autoincremento, entonces debes proporcionar un valor para cada una de ellas al momento de guardar un nuevo registro en la tabla, a menos que tu tabla cuente con una función de generación de clave primaria.
Además, al utilizar claves primarias compuestas, debes asegurarte de que las columnas correspondientes también tengan las claves foráneas correctamente configuradas en las tablas relacionadas.
Aquí te dejo un ejemplo completo de cómo especificar múltiples claves primarias en un modelo Eloquent:
use Illuminate\Database\Eloquent\Model;
class TuModelo extends Model
{
// Define un array con las columnas que deben ser utilizadas como clave primaria
protected $primaryKey = ['columna1', 'columna2'];
// Desactiva el tratamiento de la clave primaria como autoincrementable
public $incrementing = false;
// El resto de tu modelo aquí...
}
Ahora puedes
utilizar este modelo para interactuar con tu tabla en la base de datos. Por ejemplo, para guardar un nuevo registro:
$tuModelo = new TuModelo();
$tuModelo->columna1 = 'valor1';
$tuModelo->columna2 = 'valor2';
$tuModelo->columna3 = 'valor3';
$tuModelo->save();
O para
actualizar un registro existente:
$tuModelo = TuModelo::find(['columna1' => 'valor1', 'columna2' => 'valor2']);
$tuModelo->columna3 = 'nuevo valor';
$tuModelo->save();
Ten en cuenta que cuando se utiliza una clave compuesta, el método find() se utiliza pasando un array con las claves correspondientes.