В настоящее время я работаю над проектом с несколькими доменами и языками, где видео повторно используются с разными названиями и описанием.
Мои таблицы, имеющие отношение к этому вопросу с отношениями, похожи на
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