【发布时间】:2016-02-24 18:43:12
【问题描述】:
我的帖子有图片(多对多,因为图片也可以有其他关系)。在我的数据透视表中,我有一个名为“特色”的布尔字段,用于指定该帖子的主图像。我想在帖子索引页面中显示与当前用户关联的所有帖子。我只想从数据库中获取一张图片,那应该是特色图片。目前我只能将精选图像作为一个集合来获取。这样做的原因是,如果用户有很多帖子,我不想继续检索他们所有帖子 (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
我该怎么做?
【问题讨论】:
-
->get()将始终返回 collection 无论实际输出是什么,而->first()将返回第一个输出作为 model。那么问题是,如何constraint eagerload 为每个给定的posts仅加载单个关系。另外,请注意关系($this->hasMany、$this->belongsToMany等)实际上是一个 QueryBuilder 实例,因此,如果您将模型放入 eagerloadwith(),它将失败。附言。 laravel 中的每个查询都由first()或get()完成,这会将其转换为模型/集合。 -
最后我不得不允许在没有任何 get 或 first 关系的情况下进行预加载。而我所做的是使用 Collection 的
first()方法并从该列表中获取唯一的项目。 -
是的,它可以这样做,但不知何故,我们不得不检索所有东西,只是为了取一个东西......这......相当......效率低下。
标签: php laravel eloquent many-to-many