Laravel报错Illuminate\Database\Eloquent\Collection::save不存在的解决求助
问题分析
报错Illuminate\Database\Eloquent\Collection::save does not exist的核心原因是:你在update模式下获取到的$mappedData是Eloquent Collection(集合)实例,而非单个ProxmoxVps模型实例,而集合没有save()方法。
出现这种情况的场景:
- 当
$requestData['id_proxmox_vps']是一个数组时,ProxmoxVps::find($requestData['id_proxmox_vps'])会返回包含多个模型的集合,而非单个模型。 - 另外如果
find()找不到对应记录,$mappedData会是null,后续赋值操作也会引发错误。
解决方案
针对单条记录新增/更新的业务场景,修改代码如下:
public function mapApiDataToModel($apiData, $requestData, $type , $mode) { // 根据模式获取模型实例,确保是单个模型或抛出异常 if ($mode == 'new'){ $mappedData = new ProxmoxVps; } elseif ($mode == 'update'){ // 确保id是单个值,用findOrFail找不到时抛出异常,避免后续空赋值 $mappedData = ProxmoxVps::findOrFail($requestData['id_proxmox_vps']); } else { // 处理非法mode的情况,可根据业务需求调整,比如抛出异常或返回null throw new \InvalidArgumentException('Invalid mode provided'); } // 以下赋值逻辑保持不变 $mappedData->id_proxmox_node = $requestData['id_proxmox_node']; $mappedData->nama = $requestData['selected_node']; $mappedData->vm_id = $apiData['vmid']; $mappedData->type = $type; $mappedData->catatan = null; $mappedData->status = $apiData['status']; $mappedData->status_ews1 = $apiData['status_ews1'] ?? 'danger'; $mappedData->status_ews2 = $apiData['status_ews2'] ?? 'normal'; $mappedData->last_update = now(); $mappedData->online = $apiData['online'] ?? 'online'; $mappedData->cpu_usage_percentage = round($apiData['cpu'] * 100, 2); $mappedData->cpu_max = $apiData['cpus']; $mappedData->ram_usage_percentage = round(($apiData['mem'] / $apiData['maxmem']) * 100, 2); $mappedData->ram_max = $apiData['maxmem'] / (1024 * 1024 * 1024); $mappedData->hd_usage_percentage = round($apiData['disk'] / (1024 * 1024), 2); $mappedData->hd_max = round($apiData['maxdisk'] / (1024 * 1024), 2); $mappedData->hd_read_utilization = round($apiData['diskread'] / (1024 * 1024), 2); $mappedData->hd_write_utilization = round($apiData['diskwrite'] / (1024 * 1024), 2); $mappedData->net_in_utilization = round($apiData['netin'] / (1024 * 1024), 2); $mappedData->net_out_utilization = round($apiData['netout'] / (1024 * 1024), 2); if ($type === "lxc") { $mappedData->sched_checking_interval = $requestData[0]['listSelectedCT']['interval'] ?? 0; } else { $mappedData->sched_checking_interval = $requestData[0]['listSelectedVM']['interval'] ?? 0; } $mappedData->sched_ews_interval = $apiData['sched_ews_interval'] ?? 0; $mappedData->sched_is_processing = false; $mappedData->ews1_warning_threshold = $requestData['ews1_warning_threshold']; $mappedData->ews1_danger_threshold = $requestData['ews1_danger_threshold']; $mappedData->ews2_sampling_count = $requestData['ews2_sampling_count']; $mappedData->ews2_percentile_warning_threshold = $requestData['ews2_percentile_warning_threshold']; $mappedData->ews2_percentile_danger_threshold = $requestData['ews2_percentile_danger_threshold'] ?? 0; $mappedData->row_status = 1; $mappedData->deleted_by = null; $mappedData->deleted_at = null; $mappedData->updated_by = $apiData['updated_by'] ?? ''; $mappedData->created_by = $apiData['created_by'] ?? ''; // 事务中执行保存 DB::transaction(function () use ($mappedData) { $mappedData->save(); Log::debug($mappedData); }); return $mappedData; }
关键修改点
- 使用
findOrFail()替代find():确保找不到对应记录时直接抛出异常,避免后续对null赋值引发错误,同时保证返回的是单个模型实例(前提是id_proxmox_vps是单个值)。 - 增加非法
mode的判断:避免未定义的模式导致$mappedData未初始化。 - 若需批量更新多条记录,需遍历集合逐个调用
save(),示例如下:
// 批量更新场景示例 elseif ($mode == 'update'){ $ids = is_array($requestData['id_proxmox_vps']) ? $requestData['id_proxmox_vps'] : [$requestData['id_proxmox_vps']]; $models = ProxmoxVps::find($ids); foreach ($models as $mappedData) { // 赋值逻辑... $mappedData->save(); } }
内容的提问来源于stack exchange,提问作者Ariel Irmawan
相关产品推荐
相关产品推荐

