Herramientas de usuario

Herramientas del sitio


informatica:programacion:php:frameworks:laravel:relaciones_entre_modelos

Diferencias

Muestra las diferencias entre dos versiones de la página.

Enlace a la vista de comparación

Ambos lados, revisión anteriorRevisión previa
Próxima revisión
Revisión previa
informatica:programacion:php:frameworks:laravel:relaciones_entre_modelos [2023/06/15 16:26] – [Relaciones muchos a muchos] tempwininformatica:programacion:php:frameworks:laravel:relaciones_entre_modelos [2025/03/11 16:28] (actual) – [Relaciones polimórficas uno a muchos] tempwin
Línea 115: Línea 115:
  
 <WRAP center round info 60%> <WRAP center round info 60%>
-Si hubiéramos puesto los paréntesis en ''payment'' u ''order'', obtendríamos un query builder que nos permitiría afinar más la consulta encadenando métodos (''$payment->order()->where(...)'')+Si hubiéramos puesto los paréntesis en ''payment'' u ''order'', obtendríamos un query builder que nos permitiría afinar más la consulta encadenando métodos (''%%$payment->order()->where(...)%%'')
 </WRAP> </WRAP>
  
Línea 412: Línea 412:
 <code> <code>
 $order->products; $order->products;
 +</code>
 +
 +===== Relaciones a través de relaciones =====
 +
 +Si miramos nuestro modelo de datos, pagos, órdenes y usuarios están relacionados. A través de la orden, podemos ver que un usuario tiene varios pagos. Esto solo será posible si el pago tiene una clave foránea de la instancia que usaremos como intermediario. En este caso es "order_at".
 +
 +Modelo de usuario (''app/Models/User.php''):
 +
 +<code php>
 +// code
 +
 +    public function payments() 
 +    {
 +        // Indicamos que queremos llegar al pago a través de la orden
 +        // Entre orden y usuario hay una clave foránea 'customer_id'
 +        return $this->hasManyThrough(Payment::class, Order::class, "customer_id")
 +    }
 +</code>
 +
 +Esta función nos permite que desde una instanacia de User podamos acceder a su lista de pagos. 
 +
 +Lo podemos ver en funcionamiento:
 +
 +<code>
 +php artisan tinker
 +</code>
 +
 +<code>
 +$user = App\Models\User::first();
 +
 +$order = $user->orders()->save(App\Models\Order::class->factory())->make());
 +
 +$user->orders;
 +
 +$payment = $order->payment()->save(App\Models\Payment::class->factory()->make());
 +
 +$user->payments;
 +</code>
 +
 +===== Relaciones polimórficas uno a uno =====
 +
 +Una imagen puede pertenecer a un producto o a un usuario.
 +
 +En la migración de las imágenes:
 +
 +<code php>
 +// code
 +    public function up() 
 +    {
 +        Schema::create("images", function (Blueprint $table) {
 +            $table->id();
 +            $table->string("path");
 +            $table->timestamps();  
 +            // Nuevo:
 +            $table->morphs("imageable");
 +        });
 +    }
 +</code>
 +
 +''%%$table->morphs()%%'' se encargará de crear los campos ''imageable_id'' e ''imageable_type''.
 +
 +Iremos a los modelos involucrados, ''Image'' y ''User''.
 +
 +<code php>
 +// code
 +class User extends Authenticatable 
 +{
 +    // code
 +    public function image() 
 +    {
 +        return $this->morphOne(Image::class, "imageable");
 +    }
 +}
 +</code>
 +
 +<code php>
 +// code
 +class Image extends Authenticatable 
 +{
 +    // code
 +    
 +    // El nombre del método lo ponemos como el del parámetro que 
 +    // le pasamos a 'morphOne' en el modelo de usuario y en 
 +    // la migración.
 +    public function imageable() 
 +    {
 +        return $this->morphTo();
 +    }
 +}
 +</code>
 +
 +===== Relaciones polimórficas uno a muchos =====
 +
 +Relación entre ''Product'' e ''Image''. Un producto puede tener múltiples imágenes.
 +
 +Con la migración vista en la sección anterior de la tabla de imágenes (donde añadimos ''%%$table->morphs('imageable')%%'', solo tenemos que ir al modelo de ''Product''.
 +
 +<code php>
 +    // code
 +    public function images() 
 +    {
 +        return $this->morphMany(Image::class, "imageable");    
 +    }    
 +</code>
 +
 +===== Relaciones polimórficas muchos a muchos =====
 +
 +Migración (se simplifican las migraciones de Producto y Orden):
 +
 +<code php>
 +class CreateProductablesTable extends Migration 
 +{
 +
 +    public function up()
 +    {
 +       Schema::create("productables", function (Blueprint $table) {
 +           $table->bigInteger("product_id")->unsigned();           
 +           $table->integer("quantity")->unsigned();
 +           $table->integer("productable");           
 +           
 +           $table->foreign("product_id")->references("id")->on("products");
 +        }); 
 +    }
 +}
 +</code>
 +
 +Ahora vamos al modelo de producto porque puede pertenecer a varios carritos y a varias órdenes:
 +
 +<code php>
 +// code
 +    public function carts() 
 +    {
 +        return $this->morphedByMany(Cart::class, "productable")->withPivot("quantity");
 +    }
 +    
 +// code
 +    public function orders() 
 +    {
 +        return $this->morphedByMany(Order::class, "productable")->withPivot("quantity");
 +    }    
 +</code>
 +
 +Ahora vamos al modelo de la orden:
 +
 +<code php>
 +// code
 +    public function products() 
 +    {
 +        return $this->morphToMany(Product::class, "productable")->withPivot("quantity");
 +    }
 +  
 +</code>
 +
 +En el modelo de Cart:
 +
 +<code php>
 +// code
 +    public function products() 
 +    {
 +        return $this->morphToMany(Product::class, "productable")->withPivot("quantity");
 +    }
 </code> </code>
informatica/programacion/php/frameworks/laravel/relaciones_entre_modelos.1686839198.txt.gz · Última modificación: por tempwin