我有一个嵌套的函数调用更新数据库中的一些数据,我要更新的列在数据库中是唯一的,它可能会更新一个重复的值,在这种情况下,我想标记为重复的模型/行
下面是我的代码的简化版本,没有嵌套函数调用
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中的唯一列(deployment_id)
,模型仍然记住try主体中给出的值,并试图用666
值更新catch中的deployment_id
。
疯狂的部分是我甚至没有在catch部分使用相同的变量!这就像他们是相互引用
唯一的办法就是
$model = $this->defaultModel->fresh();
$model->update([
'inprogress' => 0 ,
'error'=>'duplicate'
]);
型
知道为什么会这样吗
请不要建议另一种方法或方法,我知道我可以使用不同的方法....我的问题是关于模型记住catch更新时的try数据
3条答案
按热度按时间dxpyg8gm1#
Model::update()
方法是这样实现的:字符串
这意味着模型对象首先被更新,* 然后 * 保存到数据库中。如果SQL查询失败,模型将保留新的值,并且它们仍然被认为是脏的(即不与数据库同步)。
如果您再次在同一模型上调用
update()
,Eloquent将尝试保存所有脏属性(在您的情况下,包括deployment_id
)。请注意,在您的代码中,
$this->defaultModel
和$inprogress
引用相同的模型对象,因此使用其中一个或另一个将具有相同的效果。anauzrmj2#
所以PHP中的变量作用域是按函数而不是按块。所以当你在try块内赋值一个变量时,你也可以在外部访问它,只要它们在同一个函数中。这就是为什么你在catch块中看到相同的值。
p8ekf7hl3#
你需要改变你的方法,首先检查这个ID是否存在于数据库表中,如果是的话,你可以把那个条目标记为重复的,如果不是的话,你可以用你的ID更新那个列的值。