Можно ли сделать отношение 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, чтобы получить всех его работников во всех его ресторанах?






Конечно, у вас может быть метод отношений hasMany в модели Director с Нетерпеливая загрузка.
так же, как ниже
public function restaurants()
{
return $this->hasMany(Restaurant::class)->with('restaurants.workers');
}
могу предложить такое решение:
Модель директора ВАРИАНТ 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 - это именно то, что мне нужно. Еще один вопрос: с помощью функции «загрузить (что-то.другое)» можно ссылаться на любое отношение в моей модели? Даже ссылаться на одно отношение из другого?
Да, вы можете ссылаться на любое отношение вашей модели. Просто убедитесь, что все внешние ключи настроены правильно.
Вы можете определить прямую связь, «пропустив» таблицу restaurants:
class Director extends Model
{
public function workers()
{
return $this->belongsToMany(
Worker::class,
'director_restaurant',
'director_id', 'restaurant_id', null, 'restaurant_id'
);
}
}
Спасибо, но есть исключение "BelongsToMany не может быть преобразовано в строку".
Как вы его используете?
таким образом: $director = Director::find($id); вернуть $director->workers();
Используйте return $director->workers; или return $director->workers()->get();: laravel.com/docs/eloquent-relationships#querying-relationships
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, в котором вы можете определить такого рода вложенные отношения.
Спасибо за ответ!