laravel отношения многие ко многим

Отношения «Многие-ко-Многим» в Laravel Eloquent

rel many to many

В этой статье мы рассмотрим один из наиболее продвинутых типов отношений, предлагаемых Laravel Eloquent — «Многие-ко-многим».

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

Что такое отношение «Многие-ко-Многим»?

Это отношение связывает запись в таблице с одной или несколькими записями в другой таблице, и наоборот.
В отличие от «Один-ко-Многим» и «Один-к-Одному», здесь ключом является сводная таблица (pivot table), которая связывает две таблицы между собой. Сводная таблица связывает id отношения из одной модели с другими моделями и наоборот.

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

Установка Laravel

Для начала установим Laravel. Запустите команду в вашем терминале

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

Сначала создадим две модели под названием Product и Category, вместе с миграциями. Запустите команду для генерации моделей и миграций.

Как только появятся модели и миграции, обновим их:

Миграция Category

Модель Category

Миграция Product

Модель Product

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

Фиктивные данные.
Для этого урока добавьте несколько фиктивных категорий и продуктов в свою базу данных.

Создаем сводную таблицу

Нам нужно соединить эти полученные таблицы, используя таблицу ссылок, которая называется Pivot Table (Сводная Таблица). Сводная таблица — это таблица отношений, в которой содержатся идентификаторы category_id и product_id.

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

Запустите команду для генерации миграции для сводной таблицы.

Скопируйте в полученную миграцию этот код:

В приведенной выше миграции мы добавляем в таблицу три столбца: id, category_id и product_id. Обратите внимание, что мы также устанавливаем внешние ключи на соответствующие таблицы.

Теперь выполните команду, чтобы перенести эту таблицу в базу данных.

Определение отношения «Многие-ко-Многим» в Laravel Eloquent

Настало время определить отношение «Многие-ко-Многим» между моделями Category и Product используя Laravel Eloquent.

Во-первых, мы знаем, что несколько категорий принадлежат нескольким продуктам, поэтому мы можем добавить отношение belongsToMany в модель Product. Откройте класс модели Product и добавьте туда новый метод с именем categories() показано ниже:

Точно так же мы знаем, что несколько продуктов принадлежат нескольким категориям, поэтому мы можем определить отношение belongsToMany в модели Category, как показано ниже. Добавьте новый метод products() в модель Category.

Создание отношения «Многие-ко-Многим»

Теперь давайте создадим несколько категорий и продуктов, и отношения «Многие-ко-Многим» между ними. Во-первых, мы создадим несколько категорий, как показано ниже (способ добавления продуктов и категорий полностью зависит от вас).

У вас появилось несколько категорий, как это видно по вашей таблице categories.

Adding Categories

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

Этот код создаст продукт, а затем присоединит его к нескольким категориям.

Adding Product

В таблице category_product вы можете увидеть, что product_id 1 имеет несколько записей с category_id 2 и 3.

Pivot

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

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

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

Поскольку отношение«Многие-ко-Многим» всегда возвращает коллекцию (collection), вы можете использовать цикл для ее показа.

Удаление отношения «Многие-ко-Многим»

Как мы используем метод attach(), чтобы соединить модели, так же мы можем использовать detach(), чтобы удалить отношение между моделями.

Посмотрите в таблицу category_product и вы увидите, что запись category_id 2 была удалена.

Detaching Records

Заключение

В этом уроке мы рассмотрели, как можно использовать отношение «Многие-ко-Многим» в Laravel Eloquent. Я рекомендую вам потратить время на ознакомление с официальной документации Laravel.

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

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

Источник

Просто и наглядно об Отношениях в 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 Eloquent

rel one to many

В этой статье мы рассмотрим на конкретном примере, как можно создать отношение «Один-ко-Многим» в Laravel.

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

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

Например, на коммерческом сайте модель Brand принадлежит несколько записей модели Product, а модель Product принадлежит модели Brand. Эта взаимосвязь изображена на диаграмме ниже
One To Many Relationship 1

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

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

Для реализации отношения нам понадобятся две таблицы в нашей базе данных brands и products. Создадим модель и миграцию, а затем определим «Один-ко-Многим». Для генерации моделей и миграций запустите две команды в терминале

Выше приведенная команда сгенерирует в папке app две модели под названиями Brand и Product. Вы также найдете две новые миграции в папке database/migrations. Свежесозданные модели и миграция будут выглядеть следующим образом:

После того, как вы сгенерировали модели и миграции, обновите метод up() в обоих миграциях.

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

И добавляем несколько полей для таблицы продуктов. Обратите внимание на столбец brand_id, являющимся внешним ключом к идентификатору brands.

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

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

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

Откройте файл модели app/Brand.php и добавьте новую функцию с именем products(), которая будет возвращать отношение hasMany, как показано ниже:

Примечание. Мы возвращаем отношение «Один-ко-Многим» для модели бренда, которая вернёт более одной записи модели продукта, поэтому мы назвали ее во множественном числе: products. Позже, когда мы определим обратное отношение «Один-ко-Многим» в модели продукта, то будем использовать название в единственном числе: brand. У каждого продукта будет только один бренд, поэтому имя в единственном числе.

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

Поскольку мы определили отношение hasMany для модели Brand, которое вернет связанные записи модели Product, то мы можем определить обратную зависимость для модели Product.

Откройте файл модели app/Product.php и добавьте в него новый метод brand(), возвращающий бренд, который связан с этим продуктом.

После добавления нового метода brand() обновите его с помощью приведенного ниже фрагмента кода.

Как видите, в это методе мы возвращаем отношение belongsTo, которое вернут соответствующий продукту бренд.

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

После того, как определено отношения в моделях, мы можем получать связанные записи. В нашем примере, для конкретного бренда мы можем получить все связанные с ним продукты, используя метод products().

Когда мы запрашиваем продукты для бренда, то Laravel забирает из таблицы продуктов все записи, которые в поле brand_id содержать id запрошенного бренда.

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

Для обратного отношения «Один-ко-Многим», Laravel забирает из таблицу брендов запись, у которой поле идентификатора равно столбцу brand_id продукта.

Создание отношения «Один-ко-Многим»

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

Вы также можете использовать метод saveMany() вместо save() для сохранения нескольких связанных моделей.

Фильтрация отношения «Один-ко-Многим»

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

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

Удаление отношения «Один-ко-Многим»

Процесс удаления отношения такое же, как и их создание. Сначала мы получаем родительский объект — Бренд, а затем используем метод products() для удаления всех продуктов. Чтобы удалить все продукты для конкретного бренда, используйте приведенный ниже пример:

Заключение

Я старался как мог, делая эту статью насколько возможно простой, так как отношения в Laravel — самая неверно понимаемая тема. Рекомендую вам потратить немного времени на чтение официальной документации Laravel.

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

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

Источник

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