Laravel 5.2 | запросите от многих до многих к одному

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

Мои таблицы, имеющие отношение к этому вопросу с отношениями, похожи на

posts >- videos >- videos_tags -< tags id id id id domain_id video_id video_id tag_id 

Конечно, я создал модели: Post, Video и Tag со всеми необходимыми отношениями.

Я стараюсь получить все сообщения с помощью моей модели Tag и поддерживать функциональность pagination ().

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

Ближайший (я думаю) я был с этим фрагментом кода:

 // App\Models\Tag public function posts() { $posts = []; foreach ($this->videos as $video) { foreach ($video->posts as $post) { if (!array_key_exists($post->id, $posts)) $posts[$post->id] = $post; } } return \Illuminate\Database\Eloquent\Collection::make($posts); } 

Любые предложения или статьи, которые я пропустил во время поисков ответа, приветствуются 🙂

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

Это то, что я сделал:

 // App\Models\Tag public function posts() { return Post ::select('posts.*') ->join('videos', 'posts.video_id', '=', 'videos.id') ->join('videos_tags', 'videos.id', '=', 'videos_tags.video_id') ->join('tags', 'videos_tags.tag_id', '=', 'tags.id') ->where('tags.id', $this->id); } 

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

Вы можете определить так называемую область видимости в своей модели сообщений.

 class Post { /** * Limit query to posts related to a given tag id. * * @param Builder $query The original query * @param Integer $tag_id The tag id to filter for * @return Builder The query with an additional where */ public function scopeHasTag($query, $tag_id) { // assumes that there is a 'tags' relation return $query->whereHas('tags', function($tags_query) use ($tag_id) { return $tags_query->where('id', $tag_id); }); } } 

Эта область позволит вам выполнить запрос, подобный следующему ( hasTags laramagically производным от scopeHasTags ).

 $posts = Post::query()->hasTag(10); // All posts related with tag id 10 return $posts->paginate(); 

Вот официальная документация по областям запросов: https://laravel.com/docs/5.2/eloquent#local-scopes