Laravel - создание и использование связей между таблицами БД MySQL.

Laravel - создание и использование связей между таблицами БД MySQL.

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

При связывании таблиц отношением один к одному или один ко многим, нужно сначала определить какая из них является родительской - у нее связь делается по существующему первичному ключу (обычно это поле «id») и какая дочерней - в ней нужно будет создать дополнительное поле для связи с родительской таблицей, например «user_id» и внешний ключ для этого поля.

  • users – родительская таблица;
  • customers – дочерняя таблица.
Пример создания файла миграции в консоли.

Создать пустой файл миграции с названием CreateRoleTables:

Примеры миграций для создания связывающего поля/таблицы и внешних ключей.

Миграция – создание связывающего поля с внешним ключом (связь один к одному и один ко многим).Миграция для создания таблицы 'countries' со связывающим полем и внешним ключом:

Имя внешнего ключа должно быть - название владеющей модели (родительской таблицы в единственном числе) плюс _id (тут 'user_id') или указывать явно в связывающем методе модели.

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

Миграция – создание связывающей таблицы (для связи многие ко многим).

Пример связывания таблиц roles и users.Создаем таблицу role_user. Название ее не случайно - указываются две связываемые таблицы roles и users через нижнее подчеркивание в единичном числе. Или же произвольное название и тогда указывается явно в модели, в связывающем методе belongsToMany() в качестве второго аргумента.

Выборка данных, создание связывающих методов моделей. Связь "один к одному".

Например, в таблице countries создан внешний ключ для связи с таблицей users. В таком случае, таблица users является родительской и нужно создать метод hasOne() в классе ее модели User, а для модели Country создать метод belongsTo().

Создание метода для модели User:

Eloquent (реализация шаблона ActiveRecord в Larave) считает, что внешний ключ отношения называется по имени модели. В данном случае предполагается, что это user_id. Если вы хотите перекрыть стандартное имя, передайте второй параметр методу hasOne():

Получение связи (в таблице 'countries') для пользователя с > вызываем не метод, а одноименное динамическое свойство.

Создание обратной связи (для таблицы с которой связывали).Метод модели:

получение данных аналогичное:

Связь "Один ко многим".

На примере связи «один автор – несколько постов». АВТОР (таблица users) – ПОСТЫ (таблица posts).Для этого должен быть создан внешний ключ для таблицы постов. После этого в модели User можно использовать метод hasMany(), а в модели Post метод belongsTo().

Создание метода для модели User:

Получение данных: вызываем не метод, а одноименное динамическое свойство.

Создание обратной связи (для таблицы с которой связывали).Метод модели Post:

Связь "Многие ко многим".

Связываем две таблицы: roles и users создав таблицу с названием role_user. При использовании произвольного имени связывающей таблицы- название указывается явно вторым аргументом в методе belongsToMany(): так же можно перекрыть имена ключей по умолчанию:

Создание метода. Для модели User:

Для модели Role:

Получение данных: как и для других связей, вызываем не метод, а одноименное динамическое свойство "roles".Для обратной связи (другой модели), получение данных проводится аналогично.

Проверка связей при выборке.

Есть возможность отобрать данные из таблицы, только те, которые имеют связь с другой, указанной таблицей.

Например нужно отобрать всех пользователей, которые написали какие-то посты (имеют связь с таблицей постов – в таблице posts поле user_id соответствует id пользователя):

можно указать кол-во связей, которое должно быть:

можно добавить произвольное условие выборки:

Если использовать не динамическое свойство а метод связи.

В таком случае получаем HasMany Object, для получения данных из которого нужно использовать конструктор запросов: то есть можно создать дополнительные условия для выборки.

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

Вставка данных.

Для того, чтобы автоматически заполнялись связывающие поля между таблицами, для вставки данных нужно использовать специальные методы (аналогичные для любых типов связей):

Один из 2-х способов: или

При использовании метода save() «массовой вставки» может появиться ошибка MassAssignmentException in Model.php line 225 это значит, что нужно разрешить вставку указанных полей в модели – метод $fillable().

Сохранить несколько связанных моделей можно так:

Аналогично и вставка для связи многие ко многим (через связывающую таблицу).Пример.Нужно создать пользователя с указанными данными и присвоить ему статус админа (в таблице roles соответствует > или в данном случае, создастся указанный пользователь в таблице users, а так же в связывающей таблице “role_user” создастся связывающая запись.

Обновление данных.

Например нужно для пользователя под (таблица users) обновить поле 'text' из связанной таблицы постов (posts)

  1. сначала получаем модель нужного пользователя;
  2. для данной модели вызываем связывающий метод;
  3. т.к. один пользователь может иметь несколько записей, оператором where уточняем какой именно пост (id=2) нужно изменить;
  4. в методе update() указываем поля и их новые значения.

Читайте так же про методы, позволяющие изменять значения связывающих полей/таблиц в моей заметке.

📎📎📎📎📎📎📎📎📎📎