Связи таблиц

$workers->pluck(‘some_attr’) — позволяет забрать из выборки определенный атрибут

$workers->pluck(‘some_attr’)->unique() — оставит только уникальные значения

Один к одному

Разберем ситуацию когда у нас есть таблица работников workers и их профили в другой таблице profiles.

В миграции profiles, worker_id внешний ключ для таблицы workers. Код ниже сделает связь на уровне базы.

$table->foreignId('worker_id')->index()->constrained('workers');

Переходим в модель Profile (таблицы profiles) и делаем связь уже на уровне ларавель.

 public function worker()
  {
    return $this->belongsTo(Worker::class, 'worker_id', 'id');
  }

Название метода должно совпадать с названием основной модели, в данном случае Worker (таблицы workers).

Теперь этот метод можно вызвать при поиске профиля работника из таблицы profiles. В ответе будут данные работника из таблицы workers

$profile = Profile::find(1);
$worker_data = $profile->worker->toArray();

Возвращаемся в модель Worker таблицы workers и создадим такую же связь но уже для получения данных профиля при поиске данных о работнике

 public function profile()
{
return $this->hasOne(Profile::class, 'worker_id', 'id');
}

Один ко многим

Теперь у работников появляются должности в табличке positions. У одного работника может быть только одна должность но на каждую должность может быть много работников.

В миграции для таблицы workers указываем связь на уровне базы с таблицей positions

$table->foreignId('position_id')->nullable()->index()->constrained('positions');

В модели Worker добавляем метод для поиска данных о должности работника

public function position()
  {
    return $this->belongsTo(Position::class, 'position_id', 'id');
  }

Теперь при поиске можно получить данные о должности

$worker = Worker::find(1);
$position_data = $worker->position->toArray();

Для поиска всех работников с конкретной должностью в модели Position создадим метод

 public function workers()
  {
    return $this->hasMany(Worker::class, 'position_id', 'id');
  }

Теперь при поиске можно получить список работников

$position = Position::find(1);
$workers_list = $position->workers->toArray();

Многие ко многим

Существует несколько проектов где отдельным проектом занимается несколько работников и у конкретного работника может быть несколько проектов. В таких ситуациях используются промежуточные таблицы.

Создаем миграцию. Название миграции составляется из названий моделей связанных таблиц

php artisan make:model ProjectWorker -m

В миграции установим связь с таблицами. Последняя строка определяет то что не может быть дубликатов в связи столбцов проекта и работника

$table->foreignId('project_id')->index()->constrained('projects');
$table->foreignId('worker_id')->index()->constrained('workers');
$table->unique(['project_id','worker_id']);

Переходим в модель Project. Создадим метод для вывода всех работников конкретного проекта.

 public function workers()
  {
    return $this->belongsToMany(Worker::class, 'project_workers', 'project_id', 'worker_id');
  }

Класс используем той таблицы из которой нам нужны данные, вторым аргументом передаем внешний ключ таблицы из текущей модели. Последний аргумент это внешний ключ для той таблицы из которой нам нужны данные

Теперь при поиске

$project = Project::find(1);
$workers_list = $project->workers->toArray();

Если мы хотим получить список проектов у конкретного работника, переходим в модель Worker и добавим новый метод

 public function projects()
  {
    return $this->belongsToMany(Project::class, 'project_workers', 'worker_id', 'project_id');
  }

Запись в базу

Когда все связи установлены, можем достаточно просто заполнить связывающую таблицу

$worker= Worker::find(1);
$project = Project::find(1);
$worker->projects()->attach($project->id);

Для случаев когда надо актуализировать данные, при этом старые данные убрать, есть славный метод sync. Удалены будут только отсутствующие при новой записи строки

$worker->projects()->sync($project->id);

Разумеется в attach и sync можно передавать массивы

Доп приколы для изучения

hasOneThrough и hasManyThrough (22/23 записи)