0

私は3つのテーブルを持っています。

表 1: posts// ユーザーの Twitter 投稿を保存する
表 2: tags// Twitter 投稿で使用されるタグを保存する
表 3: post_tag// ピボットテーブル

今、私が欲しいのはtag、例えば「yolo」を入力して、このハッシュタグを持つすべての投稿を取得することです。これはかなり簡単で、私はこのようにしました

クラス投稿:

/**
* Get the tags associated with the post
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
*/
public function tags()
{
    return $this->belongsToMany('App\Models\Tag')->get(['tag']);
}

クラスタグ:

/**
 * Get the posts associated with the given tag
 *
 * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
 */
public function posts()
{
    return $this->belongsToMany('App\Models\Post');
}

データへのアクセス:

/** @var Tag $tag */
try {
    $tag    = Tag::where('tag', urldecode($passedTag))->firstOrFail();
    return response()->json(['posts' => $tag->posts->toArray()]);
} catch (ModelNotFoundException $e) {
    return response()->json(['errors' => 'No query results for: '. $passedTag]);
}

ただし、さらにやりたいことは、投稿に使用されている他のすべてのタグも取得することです。たとえば、投稿には と のタグがyoloありswagます。ユーザーが入力すると、この例ではyoloでタグ付けされているすべての投稿をアプリケーションに表示するyoloだけでなく、投稿に含まれる他のすべてのタグも表示する必要がありますswag。私はこのようにしました

/** @var Tag $tag */
try {
    $tag    = Tag::where('tag', urldecode($passedTag))->firstOrFail();
    $posts  = $tag->posts;
    $fData  = [];
    foreach ($posts as $index=>$post) {
        /** @var Post $post */
        $fData[$index] = $post->toArray();
        $fData[$index]['tags'] = $post->tags();
    }
    return response()->json(['posts' => $fData]);
} catch (ModelNotFoundException $e) {
    return response()->json(['errors' => 'No query results for: '. $passedTag]);
}

しかし、私はLaravel(Lumen)を初めて使用するので、もっと速い方法があると確信しています。これをより効率的に行う方法について何かアドバイスはありますか? ありがとう!:)

4

1 に答える 1

1

必要なすべてのリレーションをEager ロードできます。それらは同様に表示されますtoArray

/** @var Tag $tag */
try {
    return response()->json([
        'posts' => Tag::with('posts')->with([
            'posts.tags' => function ($query) {
                $query->addSelect(['tag']);
             }
        ])
        ->where('tag', urldecode($passedTag))
        ->firstOrFail()->posts->toArray()
    ]);
} catch (ModelNotFoundException $e) {
    return response()->json(['errors' => 'No query results for: '. $passedTag]);
}

一括読み込みとは、オブジェクト自体が取得されるときに、オブジェクトのリレーションを事前に読み込むことができることを意味します。これにより、クエリの負荷が軽減されるだけでなく、追加のループやデータベース呼び出しなしで、必要なすべてのデータが得られます。ご覧のとおり、熱心な読み込みをネストして、関係の関係を読み込むことができます -posts.tags

編集

このリレーションの熱心な読み込みにより、関連するタグからタグ列のみが取得されます。

'posts.tags' => function ($query) {
    $query->addSelect(['tag']);
}
于 2015-05-29T10:49:02.890 に答える