在对关系执行查询时避免加载所有相关记录
Avoid loading all related records when performing a query on relation
您好,HistoricData(多)与 HistoricDataGroup(一)之间存在多对一关系,如以下模型中的函数“data”中所定义:
class HistoricDataGroup 扩展模型
{
使用 HasFactory;
protected $fillable = ["name", "token", "description"];
public function data()
{
return $this->hasMany("App\Models\HistoricData");
}
public static function boot()
{
parent::boot();
static::deleting(function ($group) {
$group->data()->delete();
$group->workingData()->delete();
});
}
}
在我的控制器函数中,我想从 HistoricDataGroup 中获取字段,并根据应用于该数据的 where 子句从其相关的 HistoricData 模型中获取一些记录,然后 return 作为 json。
public function showChunk(Request $request)
{
$historic_data_group = HistoricDataGroup::find($request->id);
$result["group"] = $historic_data_group;
$result["data"] = $historic_data_group->data->where(
"id",
"<",
$request->candle_id
);
return response()->json($result);
}
但是,数据在 $result 中出现了两次,因为所有相关记录以及过滤后的相关数据都包含在内,如下面的 dd($result) 屏幕截图所示:
有没有办法在不加载所有相关记录的情况下执行此操作?
您可以使用Eloquent resources格式化您发送到前端的内容。
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class HistoricDataGroupResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
// Map your other table data
}
}
在你的控制器中
public function showChunk(Request $request)
{
$historic_data_group = HistoricDataGroup::find($request->id);
$data = $historic_data_group->data()->where("id", "<",$request->candle_id)->get();
return response()->json([
'group'=> \App\Http\Resources\HistoricDataGroupResource::make($historic_data_group),
'data'=>$data
]);
}
当您访问关系的动态 属性 时,如果关系尚未加载,它将尝试加载该关系。加载的关系包含在序列化输出中。
您可以直接查询关系对象以避免加载关系:
$data = $historic_data_group->data()->where(...)->get();
或者,如果您想使用动态 属性(假设之前已经加载了关系),您可以在模型序列化之前取消设置关系:
$historic_data_group->unsetRelation('data');
这将从序列化输出中删除它,因为它不会再被加载。还可以选择 'hiding' 关系或使用转换器来响应,例如 ApiResource 等。
您好,HistoricData(多)与 HistoricDataGroup(一)之间存在多对一关系,如以下模型中的函数“data”中所定义:
class HistoricDataGroup 扩展模型 { 使用 HasFactory;
protected $fillable = ["name", "token", "description"];
public function data()
{
return $this->hasMany("App\Models\HistoricData");
}
public static function boot()
{
parent::boot();
static::deleting(function ($group) {
$group->data()->delete();
$group->workingData()->delete();
});
}
}
在我的控制器函数中,我想从 HistoricDataGroup 中获取字段,并根据应用于该数据的 where 子句从其相关的 HistoricData 模型中获取一些记录,然后 return 作为 json。
public function showChunk(Request $request)
{
$historic_data_group = HistoricDataGroup::find($request->id);
$result["group"] = $historic_data_group;
$result["data"] = $historic_data_group->data->where(
"id",
"<",
$request->candle_id
);
return response()->json($result);
}
但是,数据在 $result 中出现了两次,因为所有相关记录以及过滤后的相关数据都包含在内,如下面的 dd($result) 屏幕截图所示:
有没有办法在不加载所有相关记录的情况下执行此操作?
您可以使用Eloquent resources格式化您发送到前端的内容。
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
class HistoricDataGroupResource extends JsonResource
{
public function toArray($request)
{
return [
'id' => $this->id,
// Map your other table data
}
}
在你的控制器中
public function showChunk(Request $request)
{
$historic_data_group = HistoricDataGroup::find($request->id);
$data = $historic_data_group->data()->where("id", "<",$request->candle_id)->get();
return response()->json([
'group'=> \App\Http\Resources\HistoricDataGroupResource::make($historic_data_group),
'data'=>$data
]);
}
当您访问关系的动态 属性 时,如果关系尚未加载,它将尝试加载该关系。加载的关系包含在序列化输出中。
您可以直接查询关系对象以避免加载关系:
$data = $historic_data_group->data()->where(...)->get();
或者,如果您想使用动态 属性(假设之前已经加载了关系),您可以在模型序列化之前取消设置关系:
$historic_data_group->unsetRelation('data');
这将从序列化输出中删除它,因为它不会再被加载。还可以选择 'hiding' 关系或使用转换器来响应,例如 ApiResource 等。