laravel отношения один к одному

Отношение «Один-к-Одному» в Laravel Eloquent

rel one to one1

Одним из основных элементов фреймворка Laravel является Eloquent ORM — система объектно-реляционного отображения. Laravel Eloquent предоставляет очень удобный способ создания отношений между моделями.

В этой статье мы рассмотрим, как мы можем создать отношение «Один-к-Одному» (One To One) в Laravel.

Что такое отношение «Один-к-Одному»?

Это отношение связывает одну запись в таблице с одной записью в другой таблице базы данных. «Один-к-Одному» является фундаментальным и очень простым в использовании.

Например, у нас есть модель User, используемая для аутентификации. И мы хотим добавить раздел управления профилем для хранения социальных ссылок на аккаунты пользователя, даты рождения и тому подобных данных. Мы можем добавить столбцы, связанные с профилем, прямо в таблицу пользователя, но это её усложнит.

Чтобы поддерживать нашу базу данных в чистоте и порядке, данные, относящиеся к аутентификации пользователей, такие как адрес электронной почты, имя пользователя и пароль мы храним в таблице пользователей. А данные, относящиеся к профилям, такие как социальные ссылки, дата рождения — в таблице профилей.

У одного пользователя может быть только один профиль, а профиль принадлежит только одному пользователю, поэтому здесь мы создаем отношения «Один-к-одному». Эта взаимосвязь изображена на диаграмме ниже.
one 1

Создание модели и миграции

Для реализации отношения «Один-к-одному» в Laravel, нам понадобятся две модели: User и Profile.

Как мы знаем, Laravel уже поставляется с моделью User, поэтому нам нужно создать модель Profile, которая будет сопоставлена с таблицей profiles в базе данных.

Чтобы создать модель Profile, используйте команду artisan:

Эта команда создаст новую модель App\Profile с файлом миграции:

и миграционный файл:

Сначала мы обновим метод up в файле миграции:

Теперь обновим модель Profile:

Выполните следующую команду, для создания таблиц:

Определение отношения «Один-к-Одному»

Как только вы создали таблицы, пришло время определить отношение «Один-к-Одному». Откройте файл User.php расположенный в папке app и добавьте новый публичный метод с именем profile в модель User.

Обычно дается такое же имя, как и у привязываемой модели, в данном случае — profile. Эта функция возвращает отношение hasOne.

Определение обратного отношения «Один-к-Одному»

Мы также можем добавить обратное отношение один к одному, добавив метод user в модель Profile

Мы добавили метод user, который возвращает отношение belongsTo, поскольку профиль принадлежит пользователю.

Получение данных «Один-к-Одному»

После того, как определили данные отношения, вы можете получить доступ к профилю пользователя, вызвав метод profile для объекта пользователя, как показано ниже

Чтобы получить профиль пользователя, Laravel будет искать внешний ключ в таблице profile под названием user_id, соответствующий идентификатору пользователя.

Создание отношений «Один-к-Одному»

Чтобы создать отношение «Один-к-Одному», мы сначала должны создать дочерний объект, являющийся объектом Profile

Теперь мы сохраним дочерний объект через родительский

Удаление отношений «Один-к-Одному»

Laravel предоставляет элегантный способ удаления дочерних записей при удалении родительской записи. Вы можете использовать метод onDelete() в своей миграции при определении ключа foriegn

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

Наш tmТелеграм-канал — следите за новостями о Laravel.

Задать вопросы по урокам можно на нашем форуме.

Источник

Laravel 8 · Eloquent · Отношения

Введение

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

Определение отношений

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

Но, прежде чем углубляться в использование отношений, давайте узнаем, как определить каждый тип отношений, поддерживаемый Eloquent.

Один к одному

Определение обратной связи Один к одному

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

Отношение «один-ко-многим» используется для определения отношений, в которых одна модель является родительской для одной или нескольких дочерних моделей. Например, пост в блоге может содержать бесконечное количество комментариев. Как и все другие отношения Eloquent, отношения «один-ко-многим» определяются путем определения метода в вашей модели Eloquent:

Поскольку все отношения также служат в качестве построителей запросов, вы можете добавить дополнительные ограничения в запрос отношения, вызвав метод comments и продолжая связывать условия с запросом:

Определение обратной связи Один ко многим

Как только связь определена, мы можем получить родительский пост комментария, обратившись к «динамическому свойству отношения» post :

Однако, если внешний ключ для ваших отношений не соответствует этим соглашениям, вы можете передать свое имя внешнего ключа в качестве второго аргумента методу belongsTo :

Модели по умолчанию

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

Один через отношение

Отношение «один-через-отношение» определяет отношение «один-к-одному» с другой моделью. Однако, это отношение указывает на то, что декларируемую модель можно сопоставить с одним экземпляром другой модели, связавшись через третью модель.

Теперь, когда мы изучили структуру таблицы для отношения, давайте определим отношения в модели Mechanic :

Первый аргумент, передаваемый методу hasOneThrough – это имя последней модели, к которой мы хотим получить доступ, а второй аргумент – это имя промежуточной (сводной) модели.

Соглашения по именованию ключей отношения Один через отношение

Многие через отношение

Теперь, когда мы изучили структуру таблицы для отношения, давайте определим отношение в модели Project :

Первый аргумент, передаваемый методу hasManyThrough – это имя последней модели, к которой мы хотим получить доступ, а второй аргумент – это имя сводной модели.

Соглашения по именованию ключей отношения Многие через отношение

Отношения Многие ко многим

Структура таблицы Многие ко многим

Структура модели Многие ко многим

Как только связь определена, вы можете получить доступ к ролям пользователя, используя динамическое свойство связи roles :

Поскольку все отношения также служат в качестве построителей запросов, вы можете добавить дополнительные ограничения к запросу отношений, вызвав метод roles и продолжив связывать условия с запросом:

Чтобы определить имя промежуточной таблицы отношения, Eloquent соединит имена двух связанных моделей в алфавитном порядке. Однако вы можете изменить это соглашение. Вы можете сделать это, передав второй аргумент методу belongsToMany :

Определение обратной связи Многие ко многим

Получение столбцов сводной таблицы

По умолчанию в модели pivot будут присутствовать только ключи модели. Если ваша промежуточная таблица содержит дополнительные атрибуты, вы должны указать их при определении отношения:

Корректировка имени атрибута pivot

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

Фильтрация запросов по столбцам сводной таблицы

Определение пользовательских моделей сводных таблиц

Если вы хотите определить собственную модель промежуточной таблицы отношения «многие-ко-многим», то вы можете вызвать метод using при определении отношения. Явные сводные модели дают вам возможность определять дополнительные методы в сводной модели.

При определении модели RoleUser вы должны расширять класс Illuminate\Database\Eloquent\Relations\Pivot :

Пользовательские сводные модели и автоинкрементные идентификаторы

Полиморфные отношения

Один к одному (полиморфное)

Структура таблицы отношения Один к одному (полиморфное)

Структура модели отношения Один к одному (полиморфное)

Давайте рассмотрим определения модели, необходимые для построения этой связи:

Получение отношения Один к одному (полиморфное)

Как только ваша таблица базы данных и модели определены, вы можете получить доступ к отношениям через свои модели. Например, чтобы получить изображение для поста, мы можем обратиться к динамическому свойству связи image :

Соглашения по именованию ключей отношения Один к одному (полиморфное)

Один ко многим (полиморфное)

Структура таблицы отношения Один ко многим (полиморфное)

Структура модели отношения Один ко многим (полиморфное)

Давайте рассмотрим определения модели, необходимые для построения этой связи:

Получение отношения Один ко многим (полиморфное)

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

Многие ко многим (полиморфное)

Структура таблицы отношения Многие ко многим (полиморфное)

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

Структура модели отношения Многие ко многим (полиморфное)

Метод morphToMany принимает имя связанной модели, а также «имя отношения». В зависимости от имени, которое мы присвоили имени нашей промежуточной таблицы и содержащихся в ней ключей, мы будем называть эту связь taggable :

Определение обратной связи Многие ко многим (полиморфное)

Метод morphedByMany принимает имя связанной модели, а также «имя отношения». В зависимости от имени, которое мы присвоили имени нашей промежуточной таблицы и содержащихся в ней ключей, мы будем называть эту связь taggable :

Получение отношения Многие ко многим (полиморфное)

Как только ваша таблица базы данных и модели определены, вы можете получить доступ к отношениям через свои модели. Например, чтобы получить доступ ко всем тегам для публикации, вы можете использовать динамическое свойство связи tags :

Именование полиморфных типов

Вы можете зарегистрировать morphMap в методе boot вашего класса App\Providers\AppServiceProvider или создать отдельного поставщика службы, если хотите.

При добавлении «карты полиморфных типов» в существующее приложение каждое значение столбца *_type в вашей базе данных, которое все еще содержит полностью определенный класс, необходимо преобразовать в его псевдоним, указанный в «карте полиморфных типов».

Динамические отношения

Вы можете использовать метод resolveRelationUsing для определения отношений между моделями Eloquent во время выполнения скрипта. Хотя обычно это не рекомендуется для нормальной разработки приложений, но иногда это может быть полезно при разработке пакетов Laravel.

Метод resolveRelationUsing принимает желаемое имя отношения в качестве своего первого аргумента. Второй аргумент, передаваемый методу, должен быть замыканием, которое принимает экземпляр модели и возвращает допустимое определение отношения Eloquent. Как правило, вы должны настроить динамические отношения в методе boot поставщика служб:

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

Запросы отношений

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

Например, представьте себе приложение для блога, в котором модель User имеет множество связанных моделей Post :

Вы можете запросить отношение posts и добавить к ним дополнительные ограничения к отношениям, например:

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

Создание цепочки выражений orWhere после отношений

Как показано в приведенном выше примере, вы можете добавлять дополнительные ограничения к отношениям при их запросе. Однако, будьте осторожны при создании цепочек выражений orWhere с отношением, поскольку предложения orWhere будут логически сгруппированы на том же уровне, что и ограничение отношения:

В приведенном выше примере будет сгенерирован следующий SQL. Как видите, выражение or предписывает запросу возвращать любого пользователя с более чем 100 голосами. Запрос больше не ограничен конкретным пользователем:

В большинстве ситуаций следует использовать логические группы для группировки условий в круглые скобки:

В приведенном выше примере будет получен следующий SQL. Обратите внимание, что логическая группировка правильно сгруппировала ограничения, и запрос остается ограниченным для конкретного пользователя:

Методы отношений против динамических свойств

Если вам не нужно добавлять дополнительные ограничения в запрос отношения Eloquent, вы можете получить доступ к отношению, как если бы это было свойство. Например, продолжая использовать наши модели User и Post из примера, мы можем получить доступ ко всем постам пользователя следующим образом:

Динамические свойства отношений выполняют «отложенную загрузку», что означает, что они будут загружать данные своих отношений только при фактическом доступе к ним. Из-за этого разработчики часто используют нетерпеливую загрузку для предварительной загрузки отношений, которые, как они знают, будут доступны после загрузки модели. Нетерпеливая загрузка обеспечивает значительное сокращение количества SQL-запросов, которые необходимо выполнить для загрузки отношений модели.

Запрос наличия отношений

При извлечении записей модели бывает необходимо ограничить результаты в зависимости от наличия связи. Например, представьте, что вы хотите получить все посты блога, содержащие хотя бы один комментарий. Для этого вы можете передать имя отношения методам has и orHas :

Вы также можете указать оператор и значение счетчика для уточнения запроса:

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

Eloquent в настоящее время не поддерживает запросы о существовании отношений между базами данных. Отношения должны существовать в одной базе данных.

Запрос отсутствия отношений

При извлечении записей модели бывает необходимо ограничить результаты на основании отсутствия связи. Например, представьте, что вы хотите получить все посты блога, которые не имеют комментариев. Для этого вы можете передать имя отношения методам doesntHave и orDoesntHave :

Вы можете использовать «точечную нотацию» для выполнения запроса к вложенным отношениям. Например, следующий запрос будет извлекать все посты, у которых нет комментариев; однако, посты с комментариями от авторов, которые не забанены, будут включены в результаты:

Запрос полиморфных отношений Morph To

Запрос всех связанных моделей

Допускается использование метасимвола подстановки * в качестве значения при передачи массива возможных полиморфных моделей. Это проинструктирует Laravel извлечь все возможные полиморфные типы из базы данных. Laravel выполнит дополнительный запрос, чтобы выполнить эту операцию:

Агрегирование связанных моделей

Подсчет связанных моделей

Вы также можете использовать псевдоним результата подсчета отношений, разрешив несколько подсчетов для одной и той же связи:

Отложенная загрузка подсчета связанных моделей

Если вам нужно установить дополнительные ограничения запроса для запроса подсчета, вы можете передать массив с ключами отношений, которые вы хотите подсчитать. Значения массива должны быть замыканиями, которые получают экземпляр построителя запросов:

Подсчет отношений и пользовательские операторы SELECT

Другие агрегатные функции

Подсчет связанных моделей отношений Morph To

Отложенная загрузка подсчета связанных моделей отношений Morph To

Нетерпеливая загрузка

Теперь давайте получим все книги и их авторов:

Этот цикл выполнит один запрос для получения всех книг из таблицы базы данных, затем еще один запрос для каждой книги, чтобы получить автора книги. Итак, если у нас есть 25 книг, приведенный выше код будет запускать 26 запросов: один для исходной книги и 25 дополнительных запросов для получения автора каждой книги.

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

Для этой операции будут выполнены только два запроса – один запрос для получения всех книг и один запрос – для получения всех авторов для всех книг:

Нетерпеливая загрузка множественных отношений

Иногда вам может понадобиться загрузить несколько разных отношений. Для этого просто передайте массив отношений методу with :

Вложенная нетерпеливая загрузка

Чтобы нетерпеливо загрузить отношения отношений, вы можете использовать «точечную нотацию». Например, давайте загрузим всех авторов книги и все личные контакты авторов:

Вложенная нетерпеливая загрузка отношений Morph To

Используя эти определения моделей и отношения, мы можем получить экземпляры модели ActivityFeed и нетерпеливо загрузить все родительские ( parentable ) модели и их соответствующие вложенные отношения:

Нетерпеливая загрузка определенных столбцов

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

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

Нетерпеливая загрузка по умолчанию

Ограничение нетерпеливой загрузки

Методы limit и take построителя запросов нельзя использовать при ограничении нетерпеливой загрузки.

Ограничение нетерпеливой загрузки отношений Morph To

Если вы хотите нетерпеливо загрузить полиморфное отношение «один-к», Eloquent выполнит несколько запросов для получения каждого типа связанной модели. Вы можете добавить дополнительные ограничения к каждому из этих запросов, используя метод constrain полиморфного отношения «один-к»:

В этом примере Eloquent будет загружать только те посты, которые не были скрыты, а видео только с типом как образовательное.

Нетерпеливая пост-загрузка

Иногда требуется нетерпеливо загрузить отношение только после получения родительской модели. Например, это может быть полезно, если вам нужно динамически решать, загружать ли связанные модели:

Если вам нужно задать дополнительные ограничения запроса нетерпеливой загрузки, вы можете передать массив с ключом отношений, которые вы хотите загрузить. Значения массива должны быть экземплярами замыкания, которые получают экземпляр запроса:

Чтобы загрузить отношение только в том случае, если оно еще не было загружено, используйте метод loadMissing :

Вложенная нетерпеливая пост-загрузка и отношения Morph To

Этот метод принимает имя полиморфного отношения «один-к» в качестве своего первого аргумента и массив пар модель / отношение в качестве второго аргумента. Чтобы проиллюстрировать этот метод, давайте рассмотрим следующую модель:

Используя эти определения моделей и отношения, мы можем получить экземпляры модели ActivityFeed и нетерпеливо загрузить все родительские ( parentable ) модели и их соответствующие вложенные отношения:

Вставка и обновление связанных моделей

Метод Save

Если вам нужно сохранить несколько связанных моделей, вы можете использовать метод saveMany :

Рекурсивное сохранение моделей и отношений

Метод Create

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

Перед использованием метода create обязательно ознакомьтесь с документацией о массовом присвоении атрибутов.

Обновление отношений Один К

Обновление отношений Многие ко многим

Присоединение / Отсоединение отношений Многие ко многим

При присоединении отношения к модели вы также можете передать массив дополнительных данных для вставки в промежуточную таблицу:

Для удобства attach и detach также принимают в качестве входных данных массивы идентификаторов:

Синхронизация ассоциаций отношений Многие ко многим

Вы также можете использовать метод sync для построения ассоциаций «многие-ко-многим». Метод sync принимает массив идентификаторов для размещения в промежуточной таблице. Любые идентификаторы, которых нет в данном массиве, будут удалены из промежуточной таблицы. Итак, после завершения этой операции в промежуточной таблице будут существовать только идентификаторы из переданного массива:

Вы также можете передать дополнительные значения промежуточной таблицы с идентификаторами:

Если вы не хотите отделять существующие связи, идентификаторы которых отсутствуют в переданном массиве, то вы можете использовать метод syncWithoutDetaching :

Переключение ассоциаций отношений Многие ко многим

Обновление записи сводной таблицы отношений Многие ко многим

Затрагивание временных меток родителя

Временные метки родительской модели будут обновлены только в том случае, если дочерняя модель обновлена с помощью метода save Eloquent.

Источник

Laravel Framework Russian Community

Пролог

Начало работы

Основы архитектуры

Основы

Фронтенд

Безопасность

Копаем глубже

База данных

Eloquent ORM

Тестирование

Официальные пакеты

Eloquent: Отношения

Введение

Ваши таблицы скорее всего как-то связаны с другими таблицами БД. Например, статья в блоге может иметь много комментариев, а заказ может быть связан с оставившим его пользователем. Eloquent упрощает работу и управление такими отношениями. Laravel поддерживает следующие типы связей:

Определение отношений

Eloquent отношения определены как функции в ваших классах модели Eloquent. С отношениями можно работать используя мощный конструктор запросов, который обеспечивает сцепку методов и возможность добавлять запросы. Например, мы можем прицепить дополнительный запрос к отношениям posts пользователя:

Но прежде чем погрузиться в использование отношений, давайте узнаем, чем они отличаются друг от друга.

Названия отношений в модели не должны совпадать с названиями её свойств (атрибутов).

Один к одному

Первый параметр, передаваемый hasOne — имя связанной модели. Как только отношение установлено, вы можете получить к нему доступ через динамические свойства Eloquent. Динамические свойства позволяют вам получить доступ к функциям отношений, если бы они были свойствами модели:

Создание обратного отношения

Модели по умолчанию

Чтобы заполнить модель по умолчанию атрибутами, вы можете передать массив или функцию замыкания методу withDefault :

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

Отношение «один ко многим» используется для определения отношений, где одна модель владеет некоторым количеством других моделей. Примером отношения «один ко многим» является статья в блоге, которая имеет «много» комментариев. Как и другие отношения Eloquent вы можете смоделировать это отношение таким образом:

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

Один ко многим (обратное отношение)

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

Структура таблиц

Структура модели

Для отношения «многие ко многим», нужно написать метод, возвращающий результат метода belongsToMany :

Теперь мы можем получить роли пользователя через динамическое свойство roles :

Как уже упоминалось ранее, чтобы определить имя для таблицы присоединения отношений, Eloquent соединит два названия взаимосвязанных моделей в алфавитном порядке. Тем не менее, вы можете переопределить имя, передав второй параметр методу belongsToMany :

Определение обратного отношения

Чтобы определить обратное отношение «многие-ко-многим», просто поместите другой вызов belongsToMany на вашу модель. Чтобы продолжить пример с ролями пользователя, давайте определим метод users для модели Role :

Получение промежуточных столбцов таблицы

Настройка имёни сводной таблицы

Теперь вы можете обращаться к сводной таблице по имени subscription :

Фильтрация отношений через столбцы промежуточной таблицы

Определение пользовательских моделей промежуточных таблиц

Вы можете комбинировать using и withPivot для получения столбцов из промежуточной таблицы. Например, так можно получить created_by и updated_by из RoleUser :

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

Один к одному через

Отношения «Один к одному через» связывают модели через одну промежуточную связь.

Например, если у каждого поставщика есть один пользователь, и каждый пользователь связан с одной записью истории пользователя, то модель поставщика может получить доступ к истории пользователя через пользователя. Структура БД:

Вы также можете задать явно названия ключей, при помощи которых осуществляются связи:

Ко многим через

Теперь, когда мы рассмотрели структуру таблицы для отношений, давайте определим отношения для модели Country :

Вы также можете задать явно названия ключей, при помощи которых осуществляются связи:

Полиформные отношения

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

Один к одному (полиморфное отношение)

Структура таблиц

Полиморфные отношения позволяют модели быть связанной с более чем одной моделью. Например, у нас используются изображения в качестве шапки для постов и профайлов пользователей. Чтобы не делать две отдельные таблицы images vs можем сделать одну с полиморфной связью к постам и пользователям. Структура таблиц будет такой:

Структура модели

Модели будут выглядеть так:

Получение отношения

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

Также вы можете использовать имя полиморфного отношения, заданного в модели:

Один ко многим (полиморфное отношение)

Структура таблиц

Полиморфное отношение «один ко многим» аналогично простому отношению «один ко многим». Однако целевая модель может принадлежать к нескольким типам моделей по одной ассоциации. Например, представьте, что пользователи вашего приложения могут комментировать и посты и видео. Используя полиморфные связи, вы можете использовать одну таблицу comments для обоих этих сценариев. Структура таблиц будет следующая:

Столбец commentable_id содержит id поста или видео, а commentable_type — имя класса модели, т.е. поста или видео.

Структура модели

Теперь давайте рассмотрим, какие определения для модели нам нужны, чтобы построить её отношения:

Получение отношений

После определения моделей и таблиц вы можете получить доступ к отношениям через модели. Например, чтобы получить все комментарии статьи, используйте динамическое свойство comments :

Многие ко многим (полиморфное отношение)

Структура таблиц

Структура модели

Обе модели Post и Video будут иметь связь morphToMany в базовом классе Eloquent через метод tags :

Определение обратного отношения

Теперь для модели Tag вы можете определить метод для каждой из моделей отношения. Для нашего примера мы определим метод posts и метод videos :

Получение отношения

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

Пользовательские полиморфные типы

Вы можете зарегистрировать morphMap в функции boot в своём AppServiceProvider или создать отдельный сервис-провайдер.

Запросы к отношениям

Допустим, у вас модель User имеет множество Post :

Вы можете использовать на отношениях любой из методов конструктора запросов.

Применение ИЛИ в отношениях

Этот запрос даст следующий SQL, что может быть не тем, что вы ожидаете получить:

В большинстве случаев для использования ИЛИ вместе с И вас следует объединять запросы в группы

Данная конструкция интерпретируется в следующий SQL-запрос:

Отношения: методы или свойства

Динамические свойства поддерживают «отложенную (ленивую) загрузку». Это означает, что данные загружаются из БД только в момент обращения к отношениям. Иногда применяют жадную загрузку, чтобы предварительно загрузить отношения, для которых известно, что они точно понадобятся. Жадная загрузка обеспечивает значительное сокращение SQL-запросов, если вы берёте не одну модель, а несколько.

Проверка существования связей при выборке

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

Вы также можете указать оператора и число, чтобы еще больше настроить запрос:

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

Выборка по отсутствию отношения

При получении записей модели бывает необходимо ограничить результаты выборки на основе отсутствия отношения. Например, если вы хотите получить все статьи, у которых нет комментариев. Для этого передайте имя отношения в метод doesntHave :

Для запроса к вложенным отношениям можно использовать dot-нотацию. Например, запросим все посты с коментариями незабаненных авторов:

Выборка по полиморфным отношениям

Чтобы проверить, существуют ли результаты по полиморфному отношению, используйте whereHasMorph :

Вместо того, чтобы передавать массив возможных полиморфных моделей, Вы можете использовать * и позволить Ларавелу получить все возможные полиморфные типы из базы данных. Для выполнения этой операции Ларавел выполнит дополнительный запрос:

Подсчёт моделей в отношении

Вы можете использовать массив для подсчёта сразу нескольких отношений, а также добавить условия к запросам:

Вы также можете создавать псевдоним для результата подсчета отношений, разрешая использовать несколько подсчетов на одном и том же отношении:

Жадная загрузка

Теперь давайте получим все книги и их авторов:

Этот цикл выполнит 1 запрос, чтобы получить все книги, затем выполнится по одному запросу для каждой книги, чтобы получить автора. Так, если бы у нас было 25 книг, этот код выполнил бы 26 запросов: 1 для исходной книги и 25 дополнительных запросов, чтобы получить автора каждой книги.

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

Для данной операции будут выполнены только два запроса:

Жадная загрузка нескольких отношений

В with можно указать массив с именами отношений для жадной загрузки:

Вложенная жадная загрузка

Вложенная жадная загрузка для полиморфных отношений

Используя эти определения моделей и связи, мы можем получить экземпляры моделей ActivityFeed и загрузить все parentable модели и их соответствующие вложенные связи:

Жадная загрузка указанных столбцов в модели отношения

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

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

Жадная загрузка по умолчанию

Для того, чтобы модель всегда подгружала указанные отношения, добавьте их в protected свойство with :

В случае, когда вам понадобится отключить дефолтную жадную загрузку, используйте метод without :

Условия для жадных загрузок

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

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

Методы limit и take в данном случае не могут быть использованы.

Отложенная жадная загрузка

Если вам нужно установить дополнительные условия, вместо имени отношения вы можете передать массив с функцией, где укажите нужные условия:

Для того, чтобы загрузить отношения, если они ещё не загружены, используйте loadMissing :

Отложенная жадная загрузка для полиморфных отношений

Этот метод принимает имя отношения morphTo в качестве первого аргумента, а массив моделей/пар отношений в качестве второго аргумента. Для иллюстрации этого метода рассмотрим следующую модель:

Используя эти определения моделей и связи, мы можем получить экземпляры моделей ActivityFeed и загрузить все parentable модели и их соответствующие вложенные отношения:

Вставка и изменение связанных моделей

Метод Save

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

Рекурсивное сохранение моделей и отношений

Если Вы хотите сохранить вашу модель и все связанные с ней отношения, вы можете использовать метод push :

Метод Create

Перед использованием метода create освежите в памяти документацию по массовому присваиванию атрибутов.

Вы можете использовать метод createMany для создания и добавления нескольких моделей:

Отношения «Принадлежит к»

Default Models

Отношения многие-ко-многим

Присоединение / Отсоединение

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

При присоединении отношения к модели вы можете также передать массив дополнительных данных, которые будут вставлены в промежуточную таблицу:

Для удобства attach и detach также принимают массивы id:

Синхронизация ассоциаций

Также вы можете передать дополнительные значения промежуточной таблицы с массивом ID:

Если вы не хотите отделять существующие ID, используйте метод syncWithoutDetaching :

Переключение ассоциаций

Сохранение дополнительных данных в связующей таблице

При работе с отношением многие-ко-многим метод save принимает вторым аргументом массив дополнительных атрибутов промежуточной таблицы:

Изменение записи в связующей таблице

Установка меток времени родителям

Источник

Понравилась статья? Поделить с друзьями:
Добавить комментарий
  • Как сделать успешный бизнес на ритуальных услугах
  • Выездной кейтеринг в России
  • Риски бизнеса: без чего не обойтись на пути к успеху
  • laravel отношения многие ко многим
  • laravel отношения между таблицами