Laravel - Eager加载多对多,只获取一条记录(不是集合)

时间:2015-11-22 17:29:12

标签: php laravel eloquent many-to-many

我的帖子有图片(多对多,因为图片也可以有其他关系)。在我的数据透视表中,我有一个名为'featured'的布尔字段,用于指定该帖子的主图像。我想在帖子索引页面中显示与当前用户关联的所有帖子。我只想从数据库中获取一个图像,这应该是特色图像。目前我只能将精选图像作为一个集合。这样做的原因是如果用户有很多帖子我不想继续并检索所有帖子的特色图片(N + 1),而是使用热切加载获得仅有2个查询的精选图像。

\\Post Model
public function images() {
    return $this->belongsToMany(Image::class);
}

public function image(){
    return $this->images()->where('featured', '=', true)->first();
}

public function featured_image(){
    return $this->images()->where('featured', '=', true);
}


\\Controller

$user = Auth::user();

$posts = $user->posts()->with('image')->get();

// throws error
//Call to undefined method Illuminate\Database\Query\Builder::addEagerConstraints()


// if I do this
$posts = $user->posts()->with('featured_image')->get();

// I get all the user's posts, I get the featured image but as a collection even if I only have one record there

我该怎么做?

2 个答案:

答案 0 :(得分:0)

我认为这可能是您想要的解决方案:

Id | ColumnName | Value
-----------------------------
1  | Column1    | Register1C1
1  | Column2    | Register1C2
1  | Column3    | Register1C3

在生成的帖子集中,每个帖子都有一个'featured_image'属性,可以像这样访问:

\\Post Model

public function images() {
    return $this->belongsToMany(Image::class);
}

public function getFeaturedImageAttribute() {
    return $this->images->where('featured', true)->first();
}


\\Controller    

$user = Auth::user();

$posts = $user->posts()->with('images')->get();

重要提示:因为访问器方法使用'$ this-> images'而不是'$ this-> images()',所以它将使用预先加载的'images'Collection的where()和first()方法运行而不是查询构建器。这导致了大量的PHP处理,但没有新的查询。

答案 1 :(得分:0)

可能它不是最好的选择,但如果你只限于两个查询,你可以做下一个:

$posts = $user->posts;
$idOfPosts = $posts->pluck('id');
$featuredImages = Image::whereIn('post_id', $idOfPosts)->where('featured', true)->get();

这不是Eager Load aprroach,而是解决了(N + 1)问题。