0

我有三张桌子。

表 1:posts// 存储用户的推特帖子
表 2:tags// 存储推特帖子中使用的标签
表 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]);
}

但是,我还想做的是获取已用于帖子的所有其他标签。例如,帖子具有标签yoloswag. 现在,当用户进入时,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

您可以急切地加载所有需要的关系。它们也将显示在其中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 回答