这是我目前的查询:
$cars = Cars::with('brand')->get();
$cars->map(function($cars){
$cars->fullName = $cars->brand->brand." ".$cars->name;
//other manipulation...
return $cars;
});
我想在模型中操作我的集合,以便我可以运行$cars = Cars::with('brand')->getWithBrand();
我该怎么做呢,所以每次运行查询时都不必编写地图函数?
答案 0 :(得分:1)
在您的特定示例中,您根本不需要使用map
来修改Collection。您可以使用Eloquent accessor在模型上定义数据库中不存在的属性。在您的示例中,您将在Cars
模型上定义以下方法:
public function getFullNameAttribute($value)
{
// make sure brand exists first
if ($this->brand) {
return $this->brand->brand.' '.$this->name;
}
// default if brand doesn't exist
return $this->name;
}
通过在Model上定义该函数,只要您尝试使用full_name
属性,就会调用该函数,如下面的代码所示:
$car = Cars::with('brand')->first();
// this will echo the result of the getFullNameAttribute method
echo $car->full_name;
如果您还希望此新属性自动显示在toArray()
或toJson()
输出中,则可以将该属性添加到$appends
Cars
属性中模型:
class Cars extends Model
{
protected $appends = ['full_name'];
public function getFullNameAttribute($value)
{
// make sure brand exists first
if ($this->brand) {
return $this->brand->brand.' '.$this->name;
}
// default if brand doesn't exist
return $this->name;
}
}
但请注意,您的自定义属性取决于相关对象。因此,如果您在没有急切加载toArray()
关系的汽车集合上做了一些意外调用toJson()
,__toString()
,brand
等的事情,这将导致N + 1查询问题。
例如:
// Bad: N+1 issue because each printed Car will execute a
// separate query to get its brand to output full_name.
echo Cars::get();
// Good: No N+1 issue because all brands are already loaded.
echo Cars::with('brand')->get();