Я использую Larvel's Eloquent ORM, и у меня возникают проблемы с загрузкой элементов для отображения.
Вот сценарий:
У меня есть таблица базы данных с именем «Отношения», эта таблица используется для хранения идентификатора пользователя и идентификатора блога, чтобы показать, какой пользователь следует за этим блоком. У меня есть таблица для блогов, описывающих блог, и у меня есть таблица для сообщений. Таблица отношений – это сводная таблица для объединения таблиц «Пользователи с таблицами». Теперь мне нужно перечислить все сообщения из всех блогов, которые следует за Пользователем в списке.
Вот моя модель пользователя:
public function following() { return $this->has_many_and_belongs_to('Blog', 'relationships', 'user_id', 'blog_id'); }
Вот моя модель блога:
public function followers() { return $this->has_many_and_belongs_to('User', 'relationships', 'blog_id', 'user_id'); } public function posts() { return $this->has_many('Post'); }
Вот как я пытаюсь получить сообщения в списке:
$posts = User::with(array('following', 'following.posts')) ->find($user->id) ->following() ->take($count) ->get();
Этот код перечисляет только фактические блоги, мне нужны их сообщения.
Благодарим вас за помощь, пожалуйста, дайте мне знать, если вам нужны подробности.
РЕШЕНИЕ:
Я немного изменил принятый ответ ниже, я решил использовать JOIN, чтобы уменьшить количество вызовов SQL до простого вызова. Вот:
$posts = Post::join('blogs', 'posts.blog_id', '=', 'blogs.id') ->join('relationships', 'blogs.id', '=', 'relationships.blog_id') ->select('posts.*') ->where('relationships.user_id', '=', $user->id) ->order_by('posts.id', 'desc') ->take($count) ->get();
Это невозможно осуществить с помощью местных методов «Красноречивый». Но вы можете использовать несколько методов Fluent для объединения этих таблиц. Например:
Отредактируйте здесь: я добавил загружаемую загрузку в запрос Post
.
$user = User::find(1); $posts = Post::with('blog') // Eager loads the blog this post belongs to ->join('blogs', 'blogs.id', '=', 'posts.blog_id') ->join('relationships', 'relationships.blog_id', '=', 'blogs.id') ->where('relationships.user_id', '=', $user->id) ->order_by('posts.id', 'desc') // Latest post first. ->limit(10) // Gets last 10 posts ->get('posts.*'); foreach ($posts as $post) { print($post->title); }
Если вам также нужен список всех блогов, которые такой пользователь делает для отображения на боковой панели, например. Вы можете использовать DYI вместо того, чтобы полагаться на Eloquent, который должен быть более быстрым и настраиваемым. Например:
$user = User::with('following')->find(1); // This creates a dictionary for faster performance further ahead $dictionary = array(); foreach ($user->following as $blog) { $dictionary[$blog->id] = $blog; } // Retrieves latest 10 posts from these blogs that he follows // Obs: Notice the array_keys here $posts = Post::where_in('blog_id', array_keys($blog_ids)) ->order_by('posts.id', 'desc') ->limit(10) ->get(); // Hydrates all posts with their owning blogs. // This avoids loading the blogs twice and has no effect // on database records. It's just a helper for views. foreach ($posts as $post) { $post->relationships['blog'] = $dictionary[$post->blog_id]; }
На вид:
foreach ($user->following as $blog) { print($blog->title); } foreach ($posts as $post) { print($post->title . ' @'. $post->blog->title); }