在Laravel中,是否有可能首先加载“第一个'来自BelongsToMany
关系的项目?如同,请从该关系返回Item
,而不是Collection
?
我尝试(并阅读)应用first()
或limit('1')
或任何其他约束不会返回单个项目
答案 0 :(得分:4)
使用accessor。
我猜您需要latest
,first
或类似集合中的单品,所以您可以这样做:
public function items()
{
return $this->belongsToMany(Item::class);
}
public function getLatestItemAttribute()
{
return $this->items->sortByDesc('created_at')->first();
}
那么你可以简单地使用:
$yourModel->latestItem; // single related model OR null
编辑:正如@Hkan在评论中提到的,上面的代码将导致获取整个集合并进行处理。也就是说,您可以使用替代关系对象并直接查询表:
public function getLatestItemAttribute()
{
return $this->items()->latest()->first();
}
但是,这样您就可以在调用$model->latestItem
时运行查询。因此,您获得了模型的新副本,而不是同一个实例,显然您可以根据用例查询数据库任意次数。
艰难但最好的方式是模仿这种关系:
public function getLatestItemAttribute()
{
if (!$this->relationLoaded('latestItem')) {
$this->setRelation('latestItem', $this->items()->latest()->first());
}
return $this->getRelation('latestItem');
}
在这种情况下,$model->latestItem
被视为任何其他单一关系,一旦加载。也就是说,无论何时调用访问器,它都将是单实例,并且在使用push
方法时将被保存。
答案 1 :(得分:0)
@djt
我正在寻找一个我可以eager load relationship with only one item
的解决方案,并尝试了所有方法,除了joins
Collection::select('items.item_name as name', 'items_sub.sub_name as subname')
->leftJoin('items_sub', function ($join) {
$join->on('items.id', '=', 'items_sub.item_id')->where('items_sub.type', '=', 0);
})->get();
通过这种方式,您可以获得所有Collection function helpers
而且它还减少了您对DB的查询量,
因为当您eager load with Eloquent
时,它会向提交至少2个查询
我添加了where
jsut作为示例。