Отношение HasMany через отношение BelongsToMany

Можно ли сделать отношение Laravel через отношения ownToMany?

У меня есть 4 таблицы:

1) Рестораны (id, name) — использует hasManyRelation с таблицей Workers

2)Директора (id, имя)

3)Directors_Restaurants(id, Director_id, restaurant_id) - сводная таблица для связи ownToMany Restaurants с директорами

3) Рабочие (id, name, restaurant_id)

С помощью этой функции в модели директоров я могу получить все подключенные рестораны.

public function restaurants()
{
    return $this->belongsToMany('App\Restaurant','director_restaurant');
}

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

$director = Director::find(1);
$director->load('restaurants.workers');
$workers = $director->restaurants->pluck('workers')->collapse();

Итак, мой вопрос: могу ли я объявить подобное отношение в моей модели Director, чтобы получить всех его работников во всех его ресторанах?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Поиск нового уровня в Laravel с помощью MeiliSearch и Scout
Laravel Scout - это популярный пакет, который предоставляет простой и удобный способ добавить полнотекстовый поиск в ваше приложение Laravel. Он...
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
Освоение архитектуры микросервисов с Laravel: Лучшие практики, преимущества и советы для разработчиков
В последние годы архитектура микросервисов приобрела популярность как способ построения масштабируемых и гибких приложений. Laravel , популярный PHP...
Как построить CRUD-приложение в Laravel
Как построить CRUD-приложение в Laravel
Laravel - это популярный PHP-фреймворк, который позволяет быстро и легко создавать веб-приложения. Одной из наиболее распространенных задач в...
0
0
226
4
Перейти к ответу Данный вопрос помечен как решенный

Ответы 4

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

так же, как ниже

public function restaurants()
{
    return $this->hasMany(Restaurant::class)->with('restaurants.workers');
}

Спасибо за ответ!

Bios90 14.05.2019 18:16
Ответ принят как подходящий

могу предложить такое решение:

Модель директора ВАРИАНТ 1

public function getAllRestaurants(){
    return $this->hasMany(Restaurant::class)->with('restaurants.workers');
}

Модель директора ВАРИАНТ 2

public function getAllRestaurants(){
    $this->load('restaurants.workers');
    return $this->restaurants->pluck('workers')->collapse();
}

Вы можете получить все рестораны в любом месте

$all_restaurants = Director::find(1)->getAllRestaurants();

Спасибо за ответ, ВАРИАНТ 2 - это именно то, что мне нужно. Еще один вопрос: с помощью функции «загрузить (что-то.другое)» можно ссылаться на любое отношение в моей модели? Даже ссылаться на одно отношение из другого?

Bios90 14.05.2019 18:15

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

Diego Cespedes 14.05.2019 18:19

Вы можете определить прямую связь, «пропустив» таблицу restaurants:

class Director extends Model
{
    public function workers()
    {
        return $this->belongsToMany(
            Worker::class,
            'director_restaurant',
            'director_id', 'restaurant_id', null, 'restaurant_id'
        );
    }
}

Спасибо, но есть исключение "BelongsToMany не может быть преобразовано в строку".

Bios90 14.05.2019 18:26

Как вы его используете?

Jonas Staudenmeir 14.05.2019 18:26

таким образом: $director = Director::find($id); вернуть $director->workers();

Bios90 14.05.2019 18:28

Используйте return $director->workers; или return $director->workers()->get();: laravel.com/docs/eloquent-relationships#querying-relationships

Jonas Staudenmeir 14.05.2019 18:30

Вы можете определить метод accessor в своей модели, чтобы скрыть часть логики.

# App/Director.php

// You'll need this line if you want this attribute to appear when you call toArray() or toJson()
// If not, you can comment it
protected $appends = ['workers'];

public function getWorkersAttribute()
{
    return $this->restaurants->pluck('workers')->collapse();
}

# Somewhere else
$director = Director::with('restaurants.workers')->find(1);
$workers = $director->workers;

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

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

# App/DirectorRestaurant.php

public function workers()
{
    return $this->hasMany(Worker::class, 'restaurant_id', 'restaurant_id');
}

# Somewhere else
$director = Director::find(1);
$workers = DirectorRestaurant::where('director_id', $director->id)->get()->each(function($q) { $q->load('workers'); });

Но я не рекомендую это, потому что это не очень читабельно.

Наконец, есть пакет staudenmeir/eloquent-has-many-deep, в котором вы можете определить такого рода вложенные отношения.

https://github.com/staudenmeir/eloquent-has-many-deep

Другие вопросы по теме