提问人:hretic 提问时间:10/24/2023 最后编辑:hretic 更新时间:11/5/2023 访问量:137
在 try/catch 中更新模型:模型记住 catch 中错误的更新值
updating model in try/catch : model remembers faulty update values in the catch
问:
我有一个嵌套函数调用来更新数据库中的一些数据,我要更新的列在数据库中是唯一的,在这种情况下,它可能会使用重复值进行更新,我想将该模型/行标记为重复
这是我的代码的简化版本,没有嵌套的函数调用
public $defaultModel ;
function errorTest(){
$this->defaultModel = $inprogress = Process::where('inprogress' , 1 )->first();
try
{
$inprogress->update( [
'deployment_id' => 666 ,
]);
}
catch (\Exception $exception)
{
$this->defaultModel->update([
'inprogress' => 0 ,
'error'=>'duplicate'
]);
}
}
当我尝试使用重复值更新模型时,我不断收到 Laravel 错误页面
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '666' for key
'process_deployment_id_unique'
起初我以为可能是我的 try/catch 不起作用并且我无法捕获错误,但是在玩了之后,我发现错误是由 catch 部分引起的
$this->defaultModel->update([
'inprogress' => 0 ,
'error'=>'duplicate'
]);
即使我没有更新 catch 中的唯一列,模型仍然会记住 try 正文中给出的值,并尝试在 catch 中使用值进行更新(deployment_id)
deployment_id
666
疯狂的部分是我什至没有在 catch 部分使用相同的变量!就好像它们在相互引用一样
唯一的解决方法是做一些类似的事情
$model = $this->defaultModel->fresh();
$model->update([
'inprogress' => 0 ,
'error'=>'duplicate'
]);
知道为什么会这样吗?
请不要建议其他方法或方法,我知道我可以使用不同的方法....我的问题是关于模型记住 CATCH 更新的尝试数据
答:
您需要更改方法,首先检查数据库表中是否存在该 ID,如果是,您可以将该条目标记为重复,如果没有,则可以使用您的 ID 更新该列值。
评论
因此,PHP 中的变量范围是按函数而不是按块。因此,当您在 try 块中分配变量时,您也可以在外部访问它,只要它们在同一个函数中即可。这就是为什么您在 catch 块中看到相同值的原因。
Model::update()
方法的实现方式如下:
return $this->fill($attributes)->save($options);
这意味着首先更新模型对象,然后保存到数据库中。如果 SQL 查询失败,模型将保留新值,并且它们仍被视为脏值(即未与数据库同步)。
如果您再次调用同一模型,Eloquent 将尝试保存所有脏属性(在您的情况下,包括 )。update()
deployment_id
请注意,在您的代码中,并引用相同的模型对象,因此使用一个或另一个将产生相同的效果。$this->defaultModel
$inprogress
评论
$original
中,将当前值保留在$attributes
中。当属性的原始值和当前值不同时,该属性是脏的。成功时,它调用 ,调用 ,复制到;因此,模型不再脏了。save()
finishSave()
syncOriginal()
$attributes
$original
$this->defaultModel->fresh()
fresh()
评论