informatica:programacion:php:frameworks:laravel:relaciones_entre_modelos
Diferencias
Muestra las diferencias entre dos versiones de la página.
| Ambos lados, revisión anteriorRevisión previaPróxima revisión | Revisión previa | ||
| informatica:programacion:php:frameworks:laravel:relaciones_entre_modelos [2023/06/13 17:18] – tempwin | informatica:programacion:php:frameworks:laravel:relaciones_entre_modelos [2025/03/11 16:28] (actual) – [Relaciones polimórficas uno a muchos] tempwin | ||
|---|---|---|---|
| Línea 3: | Línea 3: | ||
| [[informatica: | [[informatica: | ||
| + | {{ : | ||
| ===== Relaciones uno a uno ===== | ===== Relaciones uno a uno ===== | ||
| Línea 114: | Línea 115: | ||
| <WRAP center round info 60%> | <WRAP center round info 60%> | ||
| - | Si hubiéramos puesto los paréntesis en '' | + | Si hubiéramos puesto los paréntesis en '' |
| </ | </ | ||
| Línea 250: | Línea 251: | ||
| < | < | ||
| $payment-> | $payment-> | ||
| + | </ | ||
| + | |||
| + | ===== Relaciones muchos a muchos ===== | ||
| + | |||
| + | Con el ejemplo de la tienda, hay dos relaciones de muchos a muchos: | ||
| + | |||
| + | * Entre producto y orden: un producto puede pertenecer a varias órdenes; una orden puede tener varios productos. | ||
| + | * Entre producto y carrito: un carrito puede tener múltiples productos; un producto puede estar en múltiples carritos al mismo tiempo | ||
| + | |||
| + | Para construir este tipo de relaciones es necesario construir una tabla intermedia. Con las migraciones, | ||
| + | |||
| + | <code php> | ||
| + | php artisan make: | ||
| + | </ | ||
| + | |||
| + | El nombre que usemos en la migración hará que Laravel cree una tabla '' | ||
| + | |||
| + | Para la otra relación: | ||
| + | |||
| + | <code php> | ||
| + | php artisan make: | ||
| + | </ | ||
| + | |||
| + | Los ficheros con las migraciones los veremos en '' | ||
| + | |||
| + | El siguiente paso es completar las migraciones para poner las claves foráneas: | ||
| + | |||
| + | <code php> | ||
| + | // code | ||
| + | class CreateCartProductTable extends Migration | ||
| + | { | ||
| + | public function up() | ||
| + | { | ||
| + | Schema:: | ||
| + | | ||
| + | | ||
| + | | ||
| + | |||
| + | | ||
| + | | ||
| + | }); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | En cuanto a la migración de la relación órdenes y productos: | ||
| + | |||
| + | <code php> | ||
| + | // code | ||
| + | class CreateOrderProductTable extends Migration | ||
| + | { | ||
| + | public function up() | ||
| + | { | ||
| + | Schema:: | ||
| + | | ||
| + | | ||
| + | | ||
| + | |||
| + | | ||
| + | | ||
| + | }); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Ahora tenemos que modificar los modelos. '' | ||
| + | |||
| + | <code php> | ||
| + | namespace App\Models; | ||
| + | use App\Models\Product; | ||
| + | use Illuminate\Database\Eloquent\Model; | ||
| + | |||
| + | class Cart extends Model | ||
| + | { | ||
| + | // Un carrito puede tener múltiples productos | ||
| + | public function products() | ||
| + | { | ||
| + | // Además de indicar la relación, le pedimos que | ||
| + | // traiga cierto atributo. Si no lo hiciésemos, | ||
| + | // solo nos traería las claves foráneas | ||
| + | return $this-> | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Para el modelo para las órdenes, '' | ||
| + | |||
| + | <code php> | ||
| + | // code | ||
| + | class Order extends Model | ||
| + | { | ||
| + | // Una orden puede tener múltiples productos | ||
| + | public function products() | ||
| + | { | ||
| + | // Además de indicar la relación, le pedimos que | ||
| + | // traiga cierto atributo. Si no lo hiciésemos, | ||
| + | // solo nos traería las claves foráneas | ||
| + | return $this-> | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Para terminar, el modelo Producto: | ||
| + | |||
| + | <code php> | ||
| + | // code | ||
| + | |||
| + | class Product extends Model | ||
| + | { | ||
| + | protected $fillable = [ | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | " | ||
| + | ]; | ||
| + | | ||
| + | public function carts() { | ||
| + | return $this-> | ||
| + | } | ||
| + | | ||
| + | public function orders() { | ||
| + | return $this-> | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Ya estaríamos listos para ejecutar las migraciones: | ||
| + | |||
| + | < | ||
| + | php artisan migrate: | ||
| + | </ | ||
| + | |||
| + | Podemos ahora hacer pruebas con: | ||
| + | |||
| + | < | ||
| + | php artisan tinker | ||
| + | </ | ||
| + | |||
| + | < | ||
| + | $user = App\Models\User:: | ||
| + | |||
| + | $order = App\Models\Order:: | ||
| + | |||
| + | $cart = App\Models\Cart:: | ||
| + | |||
| + | $product = App\Models\Product:: | ||
| + | </ | ||
| + | |||
| + | Ahora para relacionar: | ||
| + | |||
| + | < | ||
| + | $order-> | ||
| + | |||
| + | $order = $order-> | ||
| + | </ | ||
| + | |||
| + | Acceder a los productos: | ||
| + | |||
| + | < | ||
| + | $order-> | ||
| + | </ | ||
| + | |||
| + | ===== 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 " | ||
| + | |||
| + | Modelo de usuario ('' | ||
| + | |||
| + | <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 ' | ||
| + | return $this-> | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Esta función nos permite que desde una instanacia de User podamos acceder a su lista de pagos. | ||
| + | |||
| + | Lo podemos ver en funcionamiento: | ||
| + | |||
| + | < | ||
| + | php artisan tinker | ||
| + | </ | ||
| + | |||
| + | < | ||
| + | $user = App\Models\User:: | ||
| + | |||
| + | $order = $user-> | ||
| + | |||
| + | $user-> | ||
| + | |||
| + | $payment = $order-> | ||
| + | |||
| + | $user-> | ||
| + | </ | ||
| + | |||
| + | ===== 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:: | ||
| + | $table-> | ||
| + | $table-> | ||
| + | $table-> | ||
| + | // Nuevo: | ||
| + | $table-> | ||
| + | }); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | '' | ||
| + | |||
| + | Iremos a los modelos involucrados, | ||
| + | |||
| + | <code php> | ||
| + | // code | ||
| + | class User extends Authenticatable | ||
| + | { | ||
| + | // code | ||
| + | public function image() | ||
| + | { | ||
| + | return $this-> | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | <code php> | ||
| + | // code | ||
| + | class Image extends Authenticatable | ||
| + | { | ||
| + | // code | ||
| + | | ||
| + | // El nombre del método lo ponemos como el del parámetro que | ||
| + | // le pasamos a ' | ||
| + | // la migración. | ||
| + | public function imageable() | ||
| + | { | ||
| + | return $this-> | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== Relaciones polimórficas uno a muchos ===== | ||
| + | |||
| + | Relación entre '' | ||
| + | |||
| + | Con la migración vista en la sección anterior de la tabla de imágenes (donde añadimos '' | ||
| + | |||
| + | <code php> | ||
| + | // code | ||
| + | public function images() | ||
| + | { | ||
| + | return $this-> | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== 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() | ||
| + | { | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | |||
| + | | ||
| + | }); | ||
| + | } | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Ahora vamos al modelo de producto porque puede pertenecer a varios carritos y a varias órdenes: | ||
| + | |||
| + | <code php> | ||
| + | // code | ||
| + | public function carts() | ||
| + | { | ||
| + | return $this-> | ||
| + | } | ||
| + | | ||
| + | // code | ||
| + | public function orders() | ||
| + | { | ||
| + | return $this-> | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | Ahora vamos al modelo de la orden: | ||
| + | |||
| + | <code php> | ||
| + | // code | ||
| + | public function products() | ||
| + | { | ||
| + | return $this-> | ||
| + | } | ||
| + | | ||
| + | </ | ||
| + | |||
| + | En el modelo de Cart: | ||
| + | |||
| + | <code php> | ||
| + | // code | ||
| + | public function products() | ||
| + | { | ||
| + | return $this-> | ||
| + | } | ||
| </ | </ | ||
informatica/programacion/php/frameworks/laravel/relaciones_entre_modelos.1686669486.txt.gz · Última modificación: por tempwin
