Laravel 5.5 Шпаргалка по отношениям в Eloquent
На основе статьи https://hackernoon.com/eloquent-relationships-cheat-sheet-5155498c209
Один к одному
Описание: две модели Owner (Владелец) и Car (Автомобиль) соответствующие двум таблицам owners и cars
Бизнес-логика: у владельца может быть один автомобиль, у автомобиля только один владелец.
Диаграмма отношений:
Детали: Cars должны хранить идентификатор Owner ID
Модели Eloquent:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class Owner { public function car() { return $this->hasOne(Car::class); } } class Car { public function owner() { return $this->belongsTo(Owner::class); } } |
Миграции:
1 2 3 4 5 6 7 8 9 10 11 |
Schema::create('owners', function (Blueprint $table) { $table->increments('id'); $table->string('name'); }); Schema::create('cars', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->integer('owner_id')->unsigned()->index()->nullable(); $table->foreign('owner_id')->references('id')->on('owners'); }); |
Сохранение записей:
1 2 3 4 |
// Создание отношений между Owner и Car. $owner->car()->save($car); // Создание отношений между Car и Owner. $car->owner()->associate($owner)->save(); |
Извлечение записей:
1 2 3 4 |
// Получение автомобиля владельца $owner->car; // Получение владельца автомобиля $car->owner; |
Один ко многим
Описание: две модели Thief (Вор) и Car (Автомобиль) соответствующие двум таблицам thieves и cars
Бизнес-логика: вор может угнать несколько автомобилей, автомобиль может быть угнан одним вором
Диаграмма отношений:
Детали: таблица автомобилей должна хранить идентификатор вора
Модели Eloquent:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class Thief { public function cars() { return $this->hasMany(Car::class); } } class Car { public function thief() { return $this->belongsTo(Thief::class); } } |
Миграции:
1 2 3 4 5 6 7 8 9 10 11 |
Schema::create('thieves', function (Blueprint $table) { $table->increments('id'); $table->string('name'); }); Schema::create('cars', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->integer('thief_id')->unsigned()->index()->nullable(); $table->foreign('thief_id')->references('id')->on('thieves'); }); |
Сохранение записей:
1 2 3 4 5 6 7 8 9 |
// Создание отношений между Thief и Car. $thief->cars()->saveMany([ $car1, $car2, ]); // или используем метод save() $thief->cars()->save($car); // Создание отношений между Car и Thief. $car->thief()->associate($thief)->save(); |
Извлечение записей:
1 2 3 4 |
// Получение автомобилей вора $thief->cars; // Получение вора автомобиля $car->thief; |
Полиморфные отношения один ко многим
Описание: три модели Мan (Мужчина), Woman (Женщина) и Car (Автомобиль), соответствующие таблицам men, women и cars
Бизнес-логика: мужчина (buyer) может купить несколько автомобилей, женщина (buyer) может купить несколько автомобилей, автомобиль может быть приобретен одним покупателем (мужчиной или женщиной)
Диаграмма отношений:
Детали: автомобиль должен хранить идентификатор покупателя (Buyer ID) и вид покупателя (Buyer Type). “Buyer” – это условное название группы моделей (Man и Woman). Вообще, количество моделей в ней не ограничено двумя. Buyer Type – это название модели.
Модели Eloquent:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
class Man { public function cars() { return $this->morphMany(Car::class, 'buyer'); } } class Woman { public function cars() { return $this->morphMany(Car::class, 'buyer'); } } class Car { public function buyer() { return $this->morphTo(); } } |
Миграции:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
Schema::create('men', function (Blueprint $table) { $table->increments('id'); $table->string('name'); }); Schema::create('women', function (Blueprint $table) { $table->increments('id'); $table->string('name'); }); Schema::create('cars', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->integer('buyer_id')->unsigned()->index()->nullable(); $table->string('buyer_type')->nullable(); }); |
Сохранение записей:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
// Создание отношений между покупателем (Man/Woman) и Car. $man->cars()->saveMany([ $car1, $car2, ]); $woman->cars()->saveMany([ $car1, $car2, ]); // Или используйте метод save() $man->cars()->save($car); $woman->cars()->save($car); // Создание отношений между Car и buyer (Men/Women). $car1->buyer()->associate($man)->save(); $car2->buyer()->associate($woman)->save(); |
Извлечение записей:
1 2 3 4 5 6 |
// Получение автомобилей покупателя $men->cars $women->cars // Получение покупателя автомобиля $car->buyer |
Многие ко многим
Описание: две модели Driver (Водитель) и Car (Автомобиль), три таблицы drivers, cars и сводная (pivot) таблица car_driver
Бизнес-логика: водитель может водить несколько автомобилей, данный автомобиль умеют водить несколько водителей.
Диаграмма отношений:
Детали: сводная таблица car_driver должна хранить идентификаторы водителя и автомобиля (Driver ID, Car ID)
Модели Eloquent:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class Driver { public function cars() { return $this->belongsToMany(Car::class); } } class Car { public function drivers() { return $this->belongsToMany(Driver::class); } } |
Миграции:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Schema::create('drivers', function (Blueprint $table) { $table->increments('id'); $table->string('name'); }); Schema::create('cars', function (Blueprint $table) { $table->increments('id'); $table->string('name'); }); Schema::create('car_driver', function (Blueprint $table) { $table->increments('id'); $table->integer('car_id')->unsigned()->index(); $table->foreign('car_id')->references('id')->on('cars')->onDelete('cascade'); $table->integer('driver_id')->unsigned()->index(); $table->foreign('driver_id')->references('id')->on('drivers')->onDelete('cascade'); }); |
Сохранение записей:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
// Cоздание отношений Driver и Car. $driver->cars()->attach([ $car1->id, $car2->id, ]); // или используем метод sync() для защиты от дублирования отношений $driver->cars()->sync([ $car1->id, $car2->id, ]); // Создание отношений Car и Driver. $car->drivers()->attach([ $driver1->id, $driver2->id, ]); // или используем метод sync() для защиты от дублирования отношений $car->drivers()->sync([ $driver1->id, $driver2->id, ]); |
Извлечение записей:
1 2 3 4 5 |
// Получение автомобилей водителя $driver->cars // Получение водителей автомобиля $car->drivers |
Полиморфные отношения многие ко многим
Описание: три модели Valet (Работник), Owner (Владелец) и Car (Автомобиль), четыре таблицы valets, owners, cars и drivers (сводная (pivot) таблица).
Бизнес-логика: работник может водить несколько автомобилей, владелец может водить несколько автомобилей, автомобиль может иметь несколько водителей (работник или/и владелец)
Диаграмма отношений:
Детали: сводная (pivot) таблица “drivers” должна хранить идентификатор водителя (Driver ID), тип водителя (Driver Type) и идентификатор автомобиля (Car ID). “driver (водитель)” – это название группы моделей (Valet и Owner). Количество моделей в этой группы не ограничено двумя. Тип водителя – это название модели.
Модели Eloquent:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
class Valet { public function cars() { return $this->morphToMany(Car::class, 'driver'); } } class Owner { public function cars() { return $this->morphToMany(Car::class, 'driver'); } } class Car { public function valets() { return $this->morphedByMany(Valet::class, 'driver'); } public function owners() { return $this->morphedByMany(Owner::class, 'driver'); } } |
Миграции:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Schema::create('valets', function (Blueprint $table) { $table->increments('id'); $table->string('name'); }); Schema::create('owners', function (Blueprint $table) { $table->increments('id'); $table->string('name'); }); Schema::create('drivers', function (Blueprint $table) { $table->increments('id'); $table->integer('driver_id')->unsigned()->index(); $table->string('driver_type'); $table->integer('car_id')->unsigned()->index(); $table->foreign('car_id')->references('id')->on('cars')->onDelete('cascade'); }); |
Сохранение записей:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
// Создание отношений между водителем и автомобилем $valet->cars()->saveMany([$car1, $car2]); $owner->cars()->saveMany([$car1, $car2]); // или используем метод save() $valet->cars()->save($car1); $owner->cars()->save($car1); // Создание отношений между автомобилем и водителем $car->valets()->attach([ $valet1->id, $valet2->id, ]); $car->owners()->attach([ $owner1->id, $owner2->id, ]); // или используем метод sync() для защиты от дублирования отношений $car->valets()->sync([ $valet1->id, $valet2->id, ]); $car->owners()->sync([ $owner1->id, $owner2->id, ]); |
Извлечение записей:
1 2 3 4 5 6 7 |
// Получение автомобилей водителя $valet->cars $owner->cars // Получение владельцев и работников автомобиля $car->owners $car->valets |