3

私は Laravel の Eloquent ORM を使用していますが、表示するアイテムを積極的にロードするのに問題があります。

シナリオは次のとおりです。

  • ユーザーがブログをフォロー
  • ブログには投稿があります

Relationships という名前のデータベース テーブルがあります。このテーブルは、ユーザー ID とブログ ID を格納して、どのユーザーがどのブログをフォローしているかを示すために使用されます。ブログを説明するブログ用のテーブルと、投稿用のテーブルがあります。Relationships テーブルは、Users と Blogs テーブルを一緒に接続するためのピボット テーブルになります。ここで、ユーザーがフォローしているすべてのブログからすべての投稿を一覧表示する必要があります。

ここに私のユーザーモデルがあります:

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呼び出しの量を1回の呼び出しに減らすことにしました。ここにあります:

$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();
4

1 に答える 1

4

これは、ネイティブの Eloquent メソッドでは達成できません。ただし、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);
}

たとえば、サイドバーに表示するために、そのようなユーザーがフォローしているすべてのブログのリストも必要な場合。Eloquent に頼る代わりに 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);
}
于 2013-04-30T17:26:56.987 に答える