РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
187 of 1392 menu

Метод hasManyThrough

Метод hasManyThrough определяет отношение "через" (has-many-through) в Eloquent. Он позволяет получить доступ к записям из дальней таблицы через промежуточную модель. Первым параметром передаётся имя конечной модели, вторым - имя промежуточной модели, третьим - внешний ключ на промежуточной таблице, четвёртым - внешний ключ на конечной таблице, пятым - локальный ключ промежуточной модели, шестым - локальный ключ конечной модели. Если ключи не указаны, Laravel использует стандартные соглашения.

Синтаксис

<?php Model::hasManyThrough( $related, $through, $firstKey = null, $secondKey = null, $localKey = null, $secondLocalKey = null ); ?>

Пример

Рассмотрим структуру таблиц для блога. У нас есть таблицы 'countries', 'users' и 'posts'. Через страну мы хотим получить все посты пользователей этой страны:

<?php namespace AppModels; use IlluminateDatabaseEloquentModel; use AppModelsUser; use AppModelsPost; class Country extends Model { protected $table = 'countries'; public function posts() { return $this->hasManyThrough( Post::class, User::class, 'country_id', 'user_id', 'id', 'id' ); } } ?>

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

<?php namespace AppHttpControllers; use AppModelsCountry; use AppModelsPost; class PostController extends Controller { public function index() { $country = Country::find(1); $posts = $country->posts; foreach ($posts as $post) { echo $post->title; } } } ?>

Результат выполнения кода:

["Post 1", "Post 2", "Post 3"]

Пример

Если структура таблиц соответствует стандартным соглашениям Laravel, можно сократить определение отношения. Например, для таблиц 'countries', 'users' и 'posts' с типовыми ключами:

<?php namespace AppModels; use IlluminateDatabaseEloquentModel; use AppModelsUser; use AppModelsPost; class Country extends Model { protected $table = 'countries'; public function posts() { return $this->hasManyThrough( Post::class, User::class ); } } ?>

Laravel автоматически определит, что промежуточная таблица 'users' содержит внешний ключ 'country_id', а таблица 'posts' содержит внешний ключ 'user_id'. Получим посты:

<?php namespace AppHttpControllers; use AppModelsCountry; class PostController extends Controller { public function index() { $country = Country::find(2); $posts = $country->posts()->where('status', 'published')->get(); foreach ($posts as $post) { echo $post->title . ' - ' . $post->status; } } } ?>

Результат выполнения кода:

["Post 1 - published", "Post 3 - published"]

Пример

Используем метод hasManyThrough для подсчёта количества постов пользователей каждой страны с помощью отношения:

<?php namespace AppHttpControllers; use AppModelsCountry; class CountryController extends Controller { public function index() { $countries = Country::withCount('posts')->get(); foreach ($countries as $country) { echo $country->name . ': ' . $country->posts_count; } } } ?>

Результат выполнения кода:

["USA: 5", "UK: 3", "Germany: 7"]

Пример

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

<?php namespace AppHttpControllers; use AppModelsCountry; class PostController extends Controller { public function getPosts() { $country = Country::find(1); $posts = $country->posts() ->orderBy('created_at', 'desc') ->limit(5) ->get(); foreach ($posts as $post) { echo $post->title . ' - ' . $post->created_at; } } } ?>

Результат выполнения кода:

["Post 10 - 2025-01-15", "Post 9 - 2025-01-14", "Post 8 - 2025-01-13", "Post 7 - 2025-01-12", "Post 6 - 2025-01-11"]

Смотрите также

  • метод hasMany,
    который определяет отношение "один ко многим"
  • метод hasOneThrough,
    который определяет отношение "один через"
  • метод belongsToMany,
    который определяет отношение "многие ко многим"
  • метод with,
    который выполняет жадную загрузку отношений
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить