Skip to content

<<<<<<< HEAD

Episodio 8 - Relaciones

Enlace tutorial

Laravel 11

Pequeña actualización para Laravel 11, puesto que no trae el Api por defecto.

  1. Ejecutar en la terminal
  2. ︎php artisan install:api
  3. Añadir en el archivo User.php︎
  4. use Laravel\Sanctum\HasApiTokens;
  5. La primera línea después del primer { dejar así︎
  6. use HasFactory, Notifiable, HasApiTokens;

=======

8 - Relaciones. 1:1 / 1:N / N:M ...

Enlace tutorial

>>>>>>> fe5a53abf9e80cf3b3ffe1698ffe71292e7f9bd8

Apartados/tiempos:

<<<<<<< HEAD 0:04:08 - Relación 1 A 1 0:26:57 - Usando Relaciones En Vistas 0:33:26 - Usando Relaciones En Api 0:40:17 - Relación 1 A Muchos / Muchos A 1 0:47:24 - Relación Muchos A Muchos Y Pivotes 1:10:46 - Relación 1 A 1 Indirecta O Con Modelo De Paso 1:19:15 - Relación 1 A Muchos Con Modelo De Paso (Through) 1:22:31 - Relación Polimórfica 1 A 1 1:36:38 - Relación Polimórfica 1 A Muchos / Muchos A 1 1:40:18 - Relación Polimórfica Muchos A Muchos 1:57:04 - Conclusiones ======= * 0:04:08 - Relación 1 A 1 * 0:26:57 - Usando Relaciones En Vistas * 0:33:26 - Usando Relaciones En Api * 0:40:17 - Relación 1 A Muchos / Muchos A 1 * 0:47:24 - Relación Muchos A Muchos Y Pivotes * 1:10:46 - Relación 1 A 1 Indirecta O Con Modelo De Paso * 1:19:15 - Relación 1 A Muchos Con Modelo De Paso (Through) * 1:22:31 - Relación Polimórfica 1 A 1 * 1:36:38 - Relación Polimórfica 1 A Muchos / Muchos A 1 * 1:40:18 - Relación Polimórfica Muchos A Muchos * 1:57:04 - Conclusiones

fe5a53abf9e80cf3b3ffe1698ffe71292e7f9bd8

Introducción

Las relaciones entre modelos se usan para saber en si un modelo está conectado a otro y para realizar acciones entre ellos.

Hasta ahora hemos creado modelos independientes, lo que NO es lo habitual

1737693872947

¿Cómo lo transladamos a las migraciones?

1737693940084

<<<<<<< HEAD

Relación 1-1

=======

Relación 1-1 hasOne

fe5a53abf9e80cf3b3ffe1698ffe71292e7f9bd8

1737694011324

En la relación 1-1(User posee un Phone y Phone posee la id de User) uno de los elementos debe poseer al otro y ese otro debe poseer la id del primero. En este caso:

  1. Creamos un modelo Phone con su migración php artisan make:model Phone -m
  2. En la migración de Phone hay que añadir lo siguiente:
public function up(): void
    {
        Schema::create('phones', function (Blueprint $table) {
            $table->id();
            $table->unsignedInteger('prefix');
            $table->unsignedBigInteger('phone_number');
            $table->unsignedBigInteger('user_id');
            $table->timestamps();
        });
    }

<<<<<<< HEAD - En el modelo, vamos a declarar el array guard como vacío para indicar que todos los datos son editables - En el CONTROLADOR de User se le dice al usuario que un User posee un Phone. - Para ello se crea una función HasOne (tiene) - Esta nomenclatura de POSEE/TIENE y de PERTENECE es importante tenerla muy clara, ya que es lo que vamos a implementar en código ======= - En el modelo, vamos a declarar el array guard como vacío para indicar que todos los datos son editables -

¿Qué modelo tiene la clave foránea?

Como hemos visto, es el modelo Phone el que contiene el user_id

Por lo tanto y esto suele generar confusiones al principio:

Vamos a decir que

EL USUARIO TIENE UN TELÉFONO

EL TELÉFONO PERTENECE a un usuario

Asi,

Modelo User. Lógica

  • En el modelo User se le dice al usuario que un User posee un Phone.
  • Para ello se crea una función HasOne (tiene)
  • Esta nomenclatura de POSEE/TIENE y de PERTENECE es importante tenerla muy clara, ya que es lo que vamos a implementar en código
  • La convención es que sea el nombre del modelo en minúscula, va a devolver un HasOne
  • Aquí vamos a construir la devolución de todos los datos del usuario
  • Como hemos usado la convención de nombres, podemos hacerlo de forma más simple. Ya que nuestro modelo incluye un user_id
    • Si no lo respetamos, le tenemos que decirle qué nombre tiene la clase foránea, y el id de mi modelo es el ..

      fe5a53abf9e80cf3b3ffe1698ffe71292e7f9bd8

public function phone(): HasOne
    {
<<<<<<< HEAD
        return $this->hasOne(Phone::class /*, 'user_id', 'id' //Si no se respeta la nomenclatura de nombres, Laravel no sabe a qué clave se refiere*/);
    }
  • En el modelo de Phone se le dice al usuario que un Phone pertenece a un User.
public function phone(): HasOne
    {
        return $this->hasOne(Phone::class /*, 'user_id', 'id' //Si no se respeta la nomenclatura de nombres, Laravel no sabe a qué clave se refiere*/);
    }

Usando Relaciones En Vistas

======= return $this->hasOne(Phone::class ); //Si no se respeta la nomenclatura de nombres, Laravel no sabe a qué clave se refiere habría que ponerlo de la siguiente manera //return $this->hasOne(Phone::class, 'user_id', 'id' ); }

#### Modelo Phone. Lógica

- En el **modelo** de Phone hacemos una función llamado user
- El que NO tiene la clave foránea, **PERTENECE** a..
- se le dice al usuario que un Phone pertenece a un User.

```php
<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;

class Phone extends Model
{
    //
    protected $guarded = [];//para que no se proteja ningun campo

    public function user():BelongsTo
    {
        return $this->belongsTo(User::class);
    }
}

Ya hemos completado la relación 1-1

1737735413759

Seeders

Para tener datos de prueba, vamos a generarnos unos seeders en este paso, aunque no se haga uso de factorias (se comentará la factoria que viene por defecto):

php artisan make:seeder UserSeeder

php artisan make:seeder PhoneSeeder

1737781172235

seeder/factory/faker

Se ve en profundidad en la clase 7

En el archivo DatabaseSeeder.php pricipal, en la llamada run le decimos que vamos a hacer uso de ellos para lo que el archivo se queda así:

<?php

namespace Database\Seeders;

use App\Models\User;
// use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;

class DatabaseSeeder extends Seeder
{
    /**
     * Seed the application's database.
     */
    public function run(): void
    {
        // User::factory(10)->create();

        /*
        User::factory()->create([
            'name' => 'Test User',
            'email' => 'test@example.com',
        ]);*/


        $this->call([ 
            PhoneSeeder::class, 
            UserSeeder::class
        ]);
    }
}

Nos vamos al seeder del usuario para crear unos datos de prueba:

UserSeeder.php

Vamos a generar algunos usuarios definiendo incluso su ID de la siguiente forma dentro de su UserSeeder:

Añado el modelo: use App\Models\User;

Dentro de la función run, creo un usuario:

User::create([
            'id' => 1,
            'name' => 'example',
            'email' => 'example@example.com',
            'password' => Hash::make('122345678')
    ]);

PhoneSeeder.php

Añado elmodelo use App\Models\Phone;

Igualmente, dentro de la función run(), incluyo la creación de un usuario:

    Phone::create([
            'prefix' => 34,
            'phone_number' => '123456789',
            'user_id' => 1
        ]);

db:seed -> Poblar la base de datos

De esta forma tenemos ya nuestra base de datos relacional creada, y vamos a poblarla ahora:

php artisan db:seed

  • INFO Seeding database.

1737783252721

Usando Relaciones En Vistas

Vamos ahora a recuperar esa información y visualizarla.

  • Este funcionamieto, tando en Vistas como en API es el mismo para todas las relaciones, 1:N, N:M, etc..

    fe5a53abf9e80cf3b3ffe1698ffe71292e7f9bd8

Para mostrar los datos en las vistas necesitaremos hacer uso de los controllers.

  1. Creamos el UserController con el comando:
php artisan make:controller UserController

<<<<<<< HEAD 2. Dentro del UserController importamos al usuario y creamos la función index: ======= 2. Dentro del UserController importamos al usuario y creamos la función index donde vamos a buscar a nuestro usuario mediante la función find 1. buscamos el id 1 2. y le pasamos la información a la vista con los datos de usuario 3. Fijarse que aquí no estamos buscando los datos relacionados, eso ya se ha hecho en el modelo, y tendremos acceso a ellos de forma directa.

fe5a53abf9e80cf3b3ffe1698ffe71292e7f9bd8

use App\Models\User;

public function index()
    {
        $user = User::find(1);
        return view('index', compact('user'));
    }

<<<<<<< HEAD 3. Para especificar que el contenido va a salir por algún sitio especificamos la ruta en routes/web importando el User Controller y cambiando la función get para decirle que el contenido que se va a mostrar proviene de la clase index del UserController: ======= 3. Para especificar que el contenido va a salir por algún sitio especificamos la ruta en routes/web importando el User Controller y cambiando la función get para decirle que el contenido que se va a mostrar proviene del método index del UserController:

fe5a53abf9e80cf3b3ffe1698ffe71292e7f9bd8

use App\Http\Controllers\UserController;

Route::get('/', [UserController::class, 'index'])->name('index');

<<<<<<< HEAD 4. Finalmente, en nuestras vistas creamos el archivo index.blade.php que mostrará nuestra vista y le añadimos dentro del body de la estructura HTML:

    <h1>{{ $user->phone->prefix }}</h1>
    <h1>{{ $user->phone->phone_number }}</h1>

Usando Relaciones En Api

======= 4. Finalmente, en nuestras vistas creamos el archivo index.blade.php que mostrará nuestra vista y le añadimos dentro del body de la estructura HTML 1. Observa que accedemos a los datos relacionados a través de la FUNCIÓN phone:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Relaciones</title>
</head>
<body>
    <h1>{{ $user->name }}</h1>
    <h1>{{ $user->email }}</h1>
    <h2>Datos relacionados a través de foreign key</h2>
    <h3>{{ $user->phone->prefix }} / {{ $user->phone->phone_number }}</h3>
</body>
</html>

Y ya podemos arrancar el servicio.

1737784184650

Usando Relaciones En Api

Laravel 11

Pequeña actualización para Laravel 11, puesto que no trae el Api por defecto.

  1. Ejecutar en la terminal
  2. ︎php artisan install:api
  3. Añadir en el archivo User.php︎
  4. use Laravel\Sanctum\HasApiTokens;
  5. La primera línea después del primer { dejar así︎
  6. use HasFactory, Notifiable, HasApiTokens;

1737784756873


fe5a53abf9e80cf3b3ffe1698ffe71292e7f9bd8

Para mostrar los datos en la API necesitaremos hacer uso de las resources.

  1. Para ello creamos la UserResource con el comando:
php artisan make:resource UserResource
  1. Después en la UserResource añadiremos lo siguiente en lugar del return que ya había:
return [
            'id' => $this->id,
            'name' => $this->name,
            'email' => $this->email,
<<<<<<< HEAD
=======
    //le vamos a dar un poco de formato al teléfono
>>>>>>> fe5a53abf9e80cf3b3ffe1698ffe71292e7f9bd8
            'phone' => '(' . $this->phone->prefix . ')' . $this->phone->phone_number,
        ];
  1. Y finalmente añadimos la ruta en routes/api:
Route::get('/user', function (Request $request) {
    $user = User::find(1);
    return new UserResource($user);
});

<<<<<<< HEAD

Relación 1 A Muchos / Muchos A 1

Una relación 1 a muchos se da cuando un elemento X posee muchos elementos Y pero esos elementos Y sólo son poseídos por un único elemento X. Un usuario tiene varios teléfonos y esos teléfonos son de ese usuario, no pertenecen a nadie más.

  1. Primero se modifican los modelos y se le añade:
public function phones(): HasMany
    {
        return $this->hasMany(Phone::class /*, 'user_id', 'id' //Si no se respeta la nomenclatura de nombres, Laravel no sabe a qué clave se refiere*/);
    }
  1. Deberemos crear datos para poder testear y para ello, usamos los seeders:
php artisan make:seeder UserSeeder

php artisan make:seeder PhoneSeeder

Probamos también la API

Levantamos el servicio y acudimos a nuestro Software para realizar peticiones API, en este caso la extensión Thunder Client para probar esa ruta:

1737785216972

Relación 1:N hasMany (1 a muchos / muchos a 1)

Para esta parte, vamos a utilizar el mismo ejemplo.

Una relación 1 a muchos se da cuando un elemento X posee muchos elementos Y pero esos elementos Y sólo son poseídos por un único elemento X.

Ahora, vamos a cambiar las reglas para decir que, un usuario TIENE varios teléfonos y esos teléfonos SON de ese usuario, no pertenecen a nadie más.

  1. Primero se modifican los modelos y se le añade (Comenta y añade, mejor que eliminar, para ver el progreso):
  2. En la base de datos no se va a hacer cambios, pero vamos a modificar el MODELO
  3. En primer lugar, por convención, la función ahora es plural ya que se va a devolver más de uno:
  4. Importará la librería use Illuminate\Database\Eloquent\Relations\HasMany;

Modelo Phone

public function phones(): HasMany
    {
        //1 - 1
       // return $this->hasOne(Phone::class );
       //Si no se respeta la nomenclatura de nombres, Laravel no sabe a qué clave se refiere habría que ponerlo de la siguiente manera
        //return $this->hasOne(Phone::class, 'user_id', 'id' ); 

        //1 - n
        return $this->hasMany(Phone::class );
        //Si no se respeta la nomenclatura de nombres, Laravel no sabe a qué clave se refiere*/
        //return $this->hasMany(Phone::class /*, 'user_id', 'id' );
    }
  1. Deberemos crear datos para poder testear varios telefonos y para ello, usamos los seeders

PhoneSeeder.php

fe5a53abf9e80cf3b3ffe1698ffe71292e7f9bd8

  1. Y añadimos datos a éstos para que se añadan a la base de datos como filas nuevas:
<<<<<<< HEAD
User::create([
            'id' => 1,
            'name' => 'example',
            'email' => 'example@example.com',
            'password' => Hash::make('12345678'),
        ]);

Phone::create([
            'prefix' => 34,
            'phone_number' => 66666,
            'user_id' => 1,
        ]);

// Phone::create([ 'prefix' => 34, 'phone_number' => '666666', 'user_id' => 1 ]);

    Phone::create([
        'prefix' => 34,
        'phone_number' => '777777',
        'user_id' => 1
    ]);

```

DatabaseSeeder

Comento el seeder del User Seeder para que NO se ejecute Y ejecutamos el db seed

fe5a53abf9e80cf3b3ffe1698ffe71292e7f9bd8

php artisan db:seed

[!NOTE] Para que, al hacer seed, no se vuelvan a crear de nuevo, comentamos el siguiente código:

  • Del archivo database/seeders/PhoneSeeder:

Phone::create([ 'prefix' => 34, 'phone_number' => 66666, 'user_id' => 1, ]);

  • Del archivo database/seeders/DatabaseSeeder:

UserSeeder::class,

Y volvemos a hacer:

php artisan db:seed

  1. Añadimos al archivo PhoneSeeder un nuevo phone y le hacemos el seed para que lo añada a la base de datos y seguidamente descomentamos el código anteriormente comentado:

Phone::create([ 'prefix' => 33, 'phone_number' => 77777, 'user_id' => 1, ]);

<<<<<<< HEAD 5. En ìndex.blade comentamos elcódigo dentro del body y escribimos: ======= 5. En ìndex.blade comentamos elcódigo dentro del body y escribimos para que se muestren todos los teléfonos:

fe5a53abf9e80cf3b3ffe1698ffe71292e7f9bd8

```

{{ $user->name }} Phones:

@foreach ($user->phones as $phone)
    <ul>
        <li>{{ $phone->prefix }} {{ $phone->phone_number }}</li>
    </ul>
@endforeach

`` <<<<<<< HEAD 6. Y finalmente enUserResourcesobreescribimos phone para que muestre los datos de todos los teléfonos: ======= ![1737786806745](image/readme/1737786806745.png) * Y finalmente, para el caso de la API, enUserResource` sobreescribimos phone para que muestre los datos de todos los teléfonos:

fe5a53abf9e80cf3b3ffe1698ffe71292e7f9bd8

'phones' => $this->phones

<<<<<<< HEAD

Relación Muchos A Muchos

Una relación muchos a muchos se da cuando, por ejemplo, un elemento X posee muchos elementos Y y un elemento Y es poseído por muchos elementos X. Varios usuarios tienen roles específicos pero cada rol lo poseen varios usuarios.

1737786990222

Relación Muchos A Muchos (enlace)

Esta si tiene ciertas particularidades con las anteriores, ya no hay un elemento único en una de las partes de la relación - Podemos recordar este tipo de relación relacional en diferente documentación como esta enlazada aquí 1737787426540 Una relación muchos a muchos se da cuando, por ejemplo, un elemento X posee muchos elementos Y y un elemento Y es poseído por muchos elementos X. * Varios usuarios tienen roles específicos pero cada rol lo poseen varios usuarios.

Modelo Role

fe5a53abf9e80cf3b3ffe1698ffe71292e7f9bd8

Creamos un modelo Role con su migración:

php artisan make:model Role --migration

<<<<<<< HEAD Y le añadimos un atributo name para hacer pruebas, cambiándole e el modelo el atributo protected $guarder = [].

Para relacionar de muchos a muchos necesitamos una tabla pivote para saber que roles están asociados a qué usuario:

php artisan make:migration create_role_user_table

Editamos el archivo de migración pivote que hemos creado y le añadimos:

Y le añadimos a la migración un atributo name de tipo string para hacer pruebas, ($table->string('name');) cambiándole e el modelo el atributo protected $guarded = [];

Migramos

Para relacionar de muchos a muchos necesitamos una tabla pivote para saber que roles están asociados a qué usuario

  • Es importante mantener la CONVENCIÓN de nomenclaturas para después poder mantenerlo de forma más fácil sin aportar información extra
  • nombremodelo1_nombremodelo2
  • role_user
  • En singular y ordenados alfabéticamente con barra baja
  • php artisan make:migration create_role_user_table
  • ...relationships\database\migrations/2025_01_25_065858_create_role_user_table.php] created successfully.
  • Esta es una migración pura sin modelo asociado.
  • Así sabemos qué roles están asociados a qué usuarios

1737788117553

create_role_user

Editamos el archivo de migración pivote que hemos creado: * La información mínima es el id de cada tabla relacionada * pero aquí podríamos incluir, por ejemplo en un carrito de compra, a qué precio compró en ese momento, qué cantidad de esa compra, etc, ya que en muchas ocasiones esto nos interesará. * nosotros vamos a añadir el campo added_by, para añadir quién añadió el role

fe5a53abf9e80cf3b3ffe1698ffe71292e7f9bd8

$table->unsignedBigInteger('role_id'); $table->unsignedBigInteger('user_id'); $table->string('added_by')->nullable(); //Opcional

<<<<<<< HEAD Y migramos.

Añadimos datos a la tabla Role y para ello creamos un seeder, el cuál añadimos a nuestro DatabaseSeeder y dentro del cuál creamos varios roles. Añadimos una estructura para no tener que tocar varios seeders y, en el RoleSeeder creamos la tabla que hace referencia a tanto rol como usuario para crear la relación(creamos varios de estos para ver la relación de muchos a muchos):

Y migramos.

Seeders..

php artisan make:seeder RoleSeeder Añadimos datos a la tabla Role y para ello creamos un seeder, el cuál añadimos a nuestro DatabaseSeeder y dentro del cuál creamos varios roles. $this->call([ PhoneSeeder::class, UserSeeder::class, RoleSeeder::class, ]); Y en el RoleSeeder.php incluimos 4 roles diferentes, quedando la clase así (recuerda importar la librería del modelo Role): php class RoleSeeder extends Seeder { /** * Run the database seeds. */ public function run(): void { Role::create([ 'id' => 1, 'name' => 'admin' ]); Role::create([ 'id' => 2, 'name' => 'staff' ]); Role::create([ 'id' => 3, 'name' => 'user' ]); Role::create([ 'id' => 4, 'name' => 'guest' ]); } }

Ahora en nuestro Seeder de usuario (UserSeeder.php) vamos a crear también varios usuarios:

 User::create([
            'id' => 1,
            'name' => 'example',
            'email' => 'example@example.com',
            'password' => Hash::make('122345678')
        ]);

        User::create([
            'id' => 2,
            'name' => 'example2',
            'email' => 'example2@example.com',
            'password' => Hash::make('122345678')
        ]);

        User::create([
            'id' => 3,
            'name' => 'example3',
            'email' => 'example3@example.com',
            'password' => Hash::make('122345678')
        ]);

Añadimos una estructura para no tener que tocar crear más seeders y,

en el RoleSeeder creamos la tabla que hace referencia a tanto rol como usuario para crear la relación (creamos varios de estos para ver la relación de muchos a muchos):

  • Lo hacemos directamente a través del DB, recuerda añadir más, al menos 5 de forma personalizada

    fe5a53abf9e80cf3b3ffe1698ffe71292e7f9bd8

use Illuminate\Support\Facades\DB;

<<<<<<< HEAD
DB::table('role_user')->insert([
            'role_id' => 1,
            'user_id' => 1,
            'added_by' => 'Juan',
        ]);

Posteriormente, hacemos un reset de la base de datos para no duplicar contenido:

.... En la clase RoleSeeder, método run(), Tras crear los usuarios, incluimos (y completamos) ...

DB::table('role_user')->insert([ 'role_id' => 1, 'user_id' => 1, 'added_by' => 'Antonio' ]);

    DB::table('role_user')->insert([
        'role_id' => ,
        'user_id' => ,
        'added_by' => ''
    ]);

    DB::table('role_user')->insert([
        'role_id' => ,
        'user_id' => ,
        'added_by' => ''
    ]);

    DB::table('role_user')->insert([
        'role_id' => ,
        'user_id' => ,
        'added_by' => ''
    ]);

    DB::table('role_user')->insert([
        'role_id' => ,
        'user_id' => ,
        'added_by' => ''
    ]);

``` Posteriormente, hacemos un reset de la base de datos para no duplicar contenido:

fe5a53abf9e80cf3b3ffe1698ffe71292e7f9bd8

php artisan migrate:reset

php artisan migrate

php artisan db:seed

<<<<<<< HEAD Para establecer la relación, modificamos los modelos.Para el User se crea un método como el de a continuación y para el Role s crea exactamente igual pero cambiando Role::class por User::class: =======

Relaciones BelongToMany entre modelos

Para establecer la relación, modificamos los modelos Role y User. Siempre que sea muchos amuchos, recurriremos al BelongsToMany Para el User se crea un método como el de a continuación y para el Role s crea exactamente igual pero cambiando Role::class por User::class: - Como siempre, si no hemos respetado la convencion debremos darle más datos para indicar tabla y FK - Si tiene info extra, le indicamos los pivotes con withPivot.. php <?php namespace App\Models; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\BelongsToMany; class Role extends Model { // protected $guarded = []; public function users(): BelongsToMany { return $this->belongsToMany(User::class)->withPivot('added_by'); } }

fe5a53abf9e80cf3b3ffe1698ffe71292e7f9bd8

public function roles(): BelongsToMany
    {
        return $this->belongsToMany(Role::class)->withPivot('added_by');
    }

<<<<<<< HEAD

Vistas

fe5a53abf9e80cf3b3ffe1698ffe71292e7f9bd8 Finalmente, nos vamos a la vista del usuario que es la que se mostrará y escribimos esto para hacer una prueba:

<h1>{{ $user->name }} Roles:</h1>
    @foreach ($user->roles as $role)
        <ul>
            <li>{{ $role->name }} Added by: {{ $role->pivot->added_by  }}</li>
        </ul>
    @endforeach

<<<<<<< HEAD

1737790523947

Para la API igual, me voy al UserResource y le incluyo 'roles' => $this->roles

1737790690121

Nos falta dos tipos de relaciones: las de paso, y las polimórficas

Afianza este contenido primero

Es importante afianzar el contenido anterior, ya que es la base, antes de continuar con las siguientes relaciones que son más específicas, prueba ahora a implementarla en ejemplos y/o en tu proyecto.

fe5a53abf9e80cf3b3ffe1698ffe71292e7f9bd8

Relación 1 A 1 Indirecta O Con Modelo De Paso

Una relación 1 a 1 indirecta se da cuando un elemento X posee un elemento Y el cuál posee un elemento Z pero el elemento X no tiene conexión directa con el elemento Z. Una persona posee un móvil y ese móvil posee una tarjeta Sim que la persona no puede tocar sin anter tocar el móvil.

  1. Creamos el modelo Sim con su migration.
  2. Creamos las relaciones, para ello creamos la siguiente función en el modelo de Sim y la misma función pero cambiando Phone::class por Sim::class en el modelo de Phone:
public function phone(): BelongsTo
    {
        return $this->belongsTo(Phone::class);
    }
  1. Le decimos a la migration de Sim que posee:
$table->string('serial_number');
$table->string('company');
$table->unsignedBigInteger('phone_id');
  1. Establecemos la relación de paso diciéndole a User que tiene una relación con Sim a través de Phone:
public function phoneSim(): HasOneThrough
    {
        return $this->hasOneThrough(Sim::class, Phone::class);
    }

Relación 1 A Muchos Con Modelo De Paso (Through)¡¡¡¡

Una relación 1 a muchos con modelo de paso se da cuando un elemento X posee uno o varios elemento Y el cuál posee uno o varios elementos Z pero el elemento X no tiene conexión directa con los elementos Z. Una persona posee uno o varios móviles y esos móviles posee una o varias tarjetas Sim que la persona no puede tocar sin anter tocar el móvil.

  • En los modelos añadimos las funciones con las relaciones entre ellos que en vez de ser HasOneThrough son HasManyThrough en el User y en vez de HasOne es HasMany en Phone.

Relación Polimórfica 1 A 1

Una relación polimórfica se da cuando en una relación entre 3 o más elementos, el elemento X que se asocia con más de 1 elemento Y puede que no sepa si va a ser parte del elemento Y1 o del Y2, por tanto no sabe si en sus propiedades debe albergar la id de Y1 o la id de Y2. En este caso, el elemento X está en medio de una relación polimórfica. Un usuario puede poseer una imagen de perfil y la imagen puede estar en un post pero no se sabe si esa imagen forma parte del usuario o del post, por tanto, no se sabe si debe llevar la id del usuario o la id del post.

  1. Creamos el modelo de Post con su migration y le añadimos los datos a su migration.
  2. Creamos el modelo de Image con su migration y le añadimos los datos a su migration añadiento también dos campos para la id que se relacionará con los otros modelos y para el nombre de esta imagen.
$table->unsignedBigInteger('imageable_id');
$table->string('imageable_type');
  1. Añadimos al modelo Image la función siguiente:
public function imageable()
    {
        return $this->morphTo();
    }

Conclusiones