Laravel 即使不询问属性,自定义属性也会加载关系
Laravel custom attributes loads relationships even when attribute is not asked
我有一个计算小队名称的自定义属性(让我们的前端团队生活更轻松)。
这需要加载一个关系,即使属性不是 called/asked(这种情况发生在 spatie query builder,模型上的一个 allowedAppends
数组被传递给查询构建器和带有所需附加项的 GET 参数)它仍然加载关系。
// Model
public function getSquadNameAttribute()
{
$this->loadMissing('slots');
// Note: This model's slots is guaranteed to all have the same squad name (hence the first() on slots).
$firstSlot = $this->slots->first()->loadMissing('shift.squad');
return ($firstSlot) ? $firstSlot->shift->squad->name : null;
}
// Resource
public function toArray($request)
{
return [
'id' => $this->id,
'squad_name' => $this->when(array_key_exists('squad_name', $this->resource->toArray()), $this->squad_name),
'slots' => SlotResource::collection($this->whenLoaded('slots')),
];
}
注意:如果在上面的例子中没有被询问,squad_name
不会被返回,但是不管怎样
,关系仍在加载
我找到的一个可能的解决方案是编辑资源并包含 if's,但这会大大降低代码的可读性,我个人不是粉丝。
public function toArray($request)
{
$collection = [
'id' => $this->id,
'slots' => SlotResource::collection($this->whenLoaded('slots')),
];
if (array_key_exists('squad_name', $this->resource->toArray())) {
$collection['squad_name'] = $this->squad_name;
}
return $collection;
}
是否有另一种方法可以避免加载关系,如果在没有使用多个 if 向我的资源发送垃圾邮件的情况下不询问属性?
我发现的最简单和最可靠的方法是在助手 class 中创建一个函数来帮我检查。
这样您还可以根据需要自定义它。
-- RequestHelper class
public static function inAppends(string $value)
{
$appends = strpos(request()->append, ',') !== false ? preg_split('/, ?/', request()->append) : [request()->append];
return in_array($value, $appends);
}
-- 资源
'squad_name' => $this->when(RequestHelper::inAppends('squad_name'), function () {
return $this->squad_name;
}),
我有一个计算小队名称的自定义属性(让我们的前端团队生活更轻松)。
这需要加载一个关系,即使属性不是 called/asked(这种情况发生在 spatie query builder,模型上的一个 allowedAppends
数组被传递给查询构建器和带有所需附加项的 GET 参数)它仍然加载关系。
// Model
public function getSquadNameAttribute()
{
$this->loadMissing('slots');
// Note: This model's slots is guaranteed to all have the same squad name (hence the first() on slots).
$firstSlot = $this->slots->first()->loadMissing('shift.squad');
return ($firstSlot) ? $firstSlot->shift->squad->name : null;
}
// Resource
public function toArray($request)
{
return [
'id' => $this->id,
'squad_name' => $this->when(array_key_exists('squad_name', $this->resource->toArray()), $this->squad_name),
'slots' => SlotResource::collection($this->whenLoaded('slots')),
];
}
注意:如果在上面的例子中没有被询问,squad_name
不会被返回,但是不管怎样
我找到的一个可能的解决方案是编辑资源并包含 if's,但这会大大降低代码的可读性,我个人不是粉丝。
public function toArray($request)
{
$collection = [
'id' => $this->id,
'slots' => SlotResource::collection($this->whenLoaded('slots')),
];
if (array_key_exists('squad_name', $this->resource->toArray())) {
$collection['squad_name'] = $this->squad_name;
}
return $collection;
}
是否有另一种方法可以避免加载关系,如果在没有使用多个 if 向我的资源发送垃圾邮件的情况下不询问属性?
我发现的最简单和最可靠的方法是在助手 class 中创建一个函数来帮我检查。
这样您还可以根据需要自定义它。
-- RequestHelper class
public static function inAppends(string $value)
{
$appends = strpos(request()->append, ',') !== false ? preg_split('/, ?/', request()->append) : [request()->append];
return in_array($value, $appends);
}
-- 资源
'squad_name' => $this->when(RequestHelper::inAppends('squad_name'), function () {
return $this->squad_name;
}),