致力于传承' Lavaral项目有一些数据库结构问题。
有一个数据透视表,用于将服务链接到用户。问题是桌面上没有主键。相反,它具有以下内容:
id (relates to service_id)
user_id
duration
price
问题是,在更新单个用户服务信息时,它实际上正在更新数据库中id(service_id)相同的每条记录。
示例:2个用户在数据库中具有以下内容
id = 1, user_id = 1, duration = null, price = null
id = 1, user_id = 2, duration = null, price = null
服务标识1引用服务表中记录的ID。
有一个模式为用户执行API调用以更新特定服务,此端点(精简)如下所示:
foreach ($request->services as $key => $value) {
$serviceRecord = ServiceUser::where('user_id', $userId)->where('id', $value['id'])->first();
$serviceRecord->duration = ($value['duration'] ? $value['duration'] : null);
$serviceRecord->price = ($value['price'] ? $value['price'] : null);
$serviceRecord->save();
}
目前正在使用相同的价格/期限信息更新两个用户记录。
我的问题是,现在这是一个非常大的项目,并且对ServiceUser的id字段有无数的引用。有没有办法使这个保存只更新执行first()方法时返回的记录?或者我是否需要浏览整个应用程序并更改它以便它使用此表的主键?
答案 0 :(得分:1)
Laravel的罪魁祸首是Illuminate\Database\Eloquent\Model
中的这种方法:
/**
* Set the keys for a save update query.
*
* @param \Illuminate\Database\Eloquent\Builder $query
* @return \Illuminate\Database\Eloquent\Builder
*/
protected function setKeysForSaveQuery(Builder $query)
{
$query->where($this->getKeyName(), '=', $this->getKeyForSaveQuery());
return $query;
}
这基本上将保存查询范围限定为模型的主键。但是,由于您的模型没有定义任何唯一键,因此它会相应地更新所有适用的记录,即使您只使用变量中的一个模型也是如此。
由于没有真正解决这种Eloquent耦合行为的方法,我建议您采用“简单的旧”方式进行数据库调用:
$serviceUser = new ServiceUser;
DB::table($serviceUser->getTable())
->where('user_id', $userId)
->where('id', $value['id'])
->limit(1) // This limits to only the first encountered row
->update([
'duration' => ($value['duration'] ? $value['duration'] : null),
'price' => ($value['price'] ? $value['price'] : null),
]);
祝你好运!
(免责声明:我没有测试代码,所以它可能会受到错别字的影响;要点很重要)