В предыдущей статье, я описал методы добавления записей в базу данных в фреймворке Laravel, при которых в поле связывающее таблицы (внешний ключ) или в связывающую таблицу автоматически проставляется нужное значение. Но бывают ситуации, когда в процессе работы с базой данных, может потребоваться изменить,удалить или добавить значение в поле/таблицу (внешний ключ) связывающую данную таблицу с другой, не трогая другие поля.

При этом можно воспользоваться как стандартными методами, например изменим значение поля user_id в таблице countries:
$country = Country::find(1);
$country->user_id = 3;
$country->save();
так и специальными методами Laravel.

Для этого используется метод associate().

Например для связи один к одному:
$country = Country::find(1);
$user = User::find(3);
$country->user()->associate($user);
$country->save();
изменится значение поля user_id в таблице countries. Установится значение первичного ключа связанной таблицы (3).

В данном случае, не нужно устанавливать значение полю user_id явно. Вместо этого, передается модель User соответствующая указанному id целиком.


При связи один ко многим, может потребоваться изменить значения внешних ключей сразу для нескольких строк таблицы.
$posts = Post::where('id', '<', 5)->get();
$user = User::find(3);
foreach ($posts as $post) {
    $post->user()->associate($user);
    $post->save();
}
тут изменяем значение поля user_id таблицы posts в строках, у которых id < 5. Установится значение «3».



Для связи многие ко многим (используется связанная таблица) применяется метод attach().

Например, нужно добавить роль для определенного пользователя:
$user = User::find(3);
$role_id = Role::find(2)->id;
$user->roles()->attach($role_id);
данный код создаст новую строку в связывающей таблице role_user. При этом при каждом выполнении кода будет создаваться новая, аналогичная роль (дублирование).

Если нужно удалить строку(строки) из связывающей таблицы:
$user = User::find(3);
$role_id = Role::find(2)->id;
$user->roles()->detach($role_id);

Для данных методов так же можно передавать id в массиве:
$user = User::find(1);
$user->roles()->attach([1,2,4]);

Если нужно, чтобы в связывающей таблице хранились только переданные значения:
$user = User::find(1);
$role_id = Role::find(2)->id;
$user->roles()->sync($role_id);
когда операция завершится, только переданные ID будут существовать в промежуточной таблице для данной модели.