laravel шпаргалка по отношениям

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

relationships

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

Я нарисовал все сам. Воспитал в себе художника. Извините, если почувствуете себя ущербно по сравнению с моим художественным талантом.

Один к Одному (One to One)

One to One

Дочерняя модель имеет указатель на Родителя. Удаление родительской модели оставит дочернюю модель сиротой (orphaned).

Один ко Многим (One to Many)

One to Many

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

Многие ко Многим (Many to Many)

Many to Many

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

Сводная таблица (pivot table) — вот что делает это возможным. Она связывает одну запись из одной таблицы с другой, столько раз, сколько требуется. Если сводная таблица исчезает, то обе таблицы становятся несвязанными, поскольку информация об их связи содержится только в этой таблице.

К Одному Через (Has One Through)

Has One Through

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

Has One Through database

Ко Многим Через (Has Many Through)

Has Many Through

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

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

Has Many Through database

Полиморфные Один к Одному (One to One Polymorphic)

One to One Polymorphic

Полиморфные отношения «Один к Одному» такие же, как и обычные «Один к Одному», но Дочерняя запись может указывать на разные таблицы, следовательно, на разные Родительские Модели. Для этого нужны два столбца: для таблицы и идентификатора записи.

Метод morphTo() находится в Дочерней таблице, а morphOne() — в Родительских Моделях. Другими словами, этот тип отношений позволяет Потомку иметь множество типов Родителей — звучит странно, но необходимо это отметить.

Полиморфные Один ко Многим (One to Many Polymorphic)

One to Many Polymorphic

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

Полиморфные Многие ко Многим (Many to Many Polymorphic)

Many to Many Polymorphic

То же, что «Многие ко Многим», где сводная таблица отвечает за раскрытие отношений. Для ясности: Дочерние Модели больше не ограничены одним Родительским отношением, а любым, который может это принять.

И это, практически, всё. Веселого программирования.

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

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

Источник

Отношения

Введение

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

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

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

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

Один к одному

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

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

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

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

Как и для метода PHP hasOne () вы можете указать внешний и локальный ключи, передав дополнительные параметры в метод PHP hasMany () :

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

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

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

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

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

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

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

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

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

Первый параметр, переданный в метод PHP hasManyThrough () является именем конечной модели, которую мы получаем, а второй параметр — это имя промежуточной модели.

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

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

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

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

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

Чтение полиморфного отношения

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

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

Или вы можете определить свою строку для ассоциации с моделью:

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

Полиморфные связи многие ко многим

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

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

Теперь мы готовы к установке связи с моделью. Обе модели Post и Video будут иметь связь PHP morphToMany () в базовом классе Eloquent через метод PHP tags () :

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

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

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

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

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

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

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

Вы можете запросить отношения PHP posts () и добавить дополнительные условия к запросу отношения так:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

Метод Save

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

Сохранение и отношения многие-ко-многим

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

Метод Create

Перед использованием метода PHP create () пересмотрите документацию по массовому назначению атрибутов.

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

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

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

Также Eloquent предоставляет несколько дополнительных вспомогательных методов, чтобы сделать работу со связанными моделями более удобной. Например, давайте предположим, что у пользователя может быть много ролей, и у роли может быть много пользователей. Чтобы присоединить роль к пользователю вставкой записи в промежуточную таблицу, которая присоединяется к моделям, используйте метод PHP attach () :

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

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

Изменение записи в сводной таблице

Если вам необходимо изменить существующую запись в вашей сводной таблице, используйте метод PHP updateExistingPivot () :

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

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

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

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

Сохранение дополнительных данных в сводной таблице

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

Изменение записи в сводной таблице

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

Комментарии (8)

default

Самая сложная статья при обучении 30% материала лишь понял

default

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

default

Нифига, хороший перевод. Тут некоторые вещи адаптированны для новичков. На английском некоторые вещи менее понятны, чем здесь.
Если чо — я обе версии прочитал. Причём обе по два раза. Понял примерно 70%. Некоторые вещи понял только благодаря тому, что прочитал обе версии статьи. Они слегка отличаются.

default

5021

Зато «нетерпеливая» гораздо более понятно для тех кто до сих пор был не в теме.

5340

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

Т.е в полиморфной модели в метод morphTo нужно передать теже $name, $type, $id, что и у владельцев полиморфного отношения.

P.S: Сам с толкнулся с такой проблемой, но решения или пояснения не нашел, поэтому решил оставить тут комментрай, вдруг кому пригодиться.

default

Не пойму как организовать
В разных городах есть одинаковые товары
но у них разные цены

Источник

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