使用Laravel(Lumen / Eloquent)查询多对多关系和更多数据

时间:2015-05-29 10:16:52

标签: php laravel laravel-5 lumen

我有三张桌子。

表1:posts //存储用户的推文帖子 表2:tags //存储twitter帖子中使用的标签
表3:post_tag // pivot-table

现在,我想要的是输入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)的新手,所以我很确定有更快的方法。有什么建议我会如何做到这一点更高效?谢谢! :)

1 个答案:

答案 0 :(得分:1)

你可以Eager load所有需要的关系。它们将显示在<input type="text" style="width:60%;margin-right:10px;" name="search_query" id="search_query" value="" autocomplete="off"> <div id="display_result"></div> 中。

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