我有一个带有访问器的模型,该访问器获取与之相关的最后一个元素(通过另一个表/模型)。它对于单个查询很方便,但是现在我需要做一个总结,查询花费的时间太长。
该模型称为设备,它具有以下访问器:
public function getPreviousDeviceAttribute()
{
if ($this->pos_id > 0){
$pos = Pos::find($this->pos_id);
$device = $pos->devices()->newPivot()->where([
['device_id', '<', $this->id],
['pos_id','=', $this->pos_id]
])->get()->sortByDesc('id')->first();
return $device;
} else {
return null;
}
}
我需要从Controller查询集合的所有previous_device。
这是查询:
$c_pendientes = Device::whereNotNull('fecha_instalacion')
->whereNull('fecha_reversa')
->where('pos_id', '>', 0)
->where('customer_id', 1)
->get();
$pendientes = $this->seriesPendientes($c_pendientes);
public function seriesPendientes($pendientes)
{
$count = 0;
foreach($pendientes as $device)
{
$prev = $device->previous_device;
if($prev instanceof App\Device)
{
if(is_null($prev->fecha_reversa))
{
$count++;
}
}
}
return $count;
}
编辑:
属性:
设备
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`serial` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
`rotulo` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
`code` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
`cost_center` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
`guia_recepcion` INT(11) NULL DEFAULT NULL,
`guia_reversa` INT(11) NULL DEFAULT NULL,
`pep` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
`modified_by` VARCHAR(255) NULL DEFAULT NULL COLLATE 'utf8mb4_unicode_ci',
`modified_on` DATETIME NULL DEFAULT NULL,
`fecha_recepcion` DATETIME NULL DEFAULT NULL,
`fecha_instalacion` DATETIME NULL DEFAULT NULL,
`fecha_reversa` DATETIME NULL DEFAULT NULL,
`status_id` INT(10) UNSIGNED NOT NULL,
`location_id` VARCHAR(255) NOT NULL COLLATE 'utf8mb4_unicode_ci',
`customer_id` INT(10) UNSIGNED NOT NULL,
`str_id` INT(10) UNSIGNED NOT NULL,
`model_id` INT(10) UNSIGNED NOT NULL,
`pos_id` INT(11) NOT NULL,
`user_id` INT(10) UNSIGNED NOT NULL,
`technician_id` INT(10) UNSIGNED NOT NULL,
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL
)
位置
CREATE TABLE `pos` (
`id` INT(11) NOT NULL,
`vigente` BLOB NOT NULL,
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
关系
CREATE TABLE `devices_pos` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`device_id` INT(10) UNSIGNED NOT NULL,
`pos_id` INT(10) UNSIGNED NOT NULL,
`created_at` TIMESTAMP NULL DEFAULT NULL,
`updated_at` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
答案 0 :(得分:0)
如果要为大型集合中的每个项目调用此getter,则$pos = Pos::find($this->pos_id);
行将为每个项目执行一个请求。如果尚不存在以下关系,则可以通过定义以下关系来避免它
public function pos()
{
return $this->belongsTo(Pos::class);
}
然后急于加载此关系(一个请求所有项):
$c_pendientes = Device::with('pos')
->whereNotNull('fecha_instalacion')
->whereNull('fecha_reversa')
->where('pos_id', '>', 0)
->where('customer_id', 1)
->get();
您可能也应该像这样:eagder加载pos.devices。
$c_pendientes = Device::with('pos')
->with('pos.devices')
->whereNotNull('fecha_instalacion')
->whereNull('fecha_reversa')
->where('pos_id', '>', 0)
->where('customer_id', 1)
->get();
让我知道是否有帮助。