Laravel save() 正在更新错误的 mysql 记录

Posted

技术标签:

【中文标题】Laravel save() 正在更新错误的 mysql 记录【英文标题】:Laravel save() is updating the wrong mysql record 【发布时间】:2016-06-12 19:49:24 【问题描述】:

我有一个包含 3 列的用户设置表(或见下图):user_idsettingvalue

然后我有两个功能,一个是保存时区,一个是保存时间格式。

public function setTimezone($timezone)
    $settings = UserSettingsModel::firstOrNew(['user_id' => $this->user->id, 'setting' => 'timezone']);
    $settings->setting = 'timezone';
    $settings->value   = $timezone;
    $result = $settings->save();


public function setTimeFormat($timeformat)
    $settings = UserSettingsModel::firstOrNew(['user_id' => $this->user->id, 'setting' => 'timeformat']);
    $settings->setting = 'timeformat';
    $settings->value   = $timeformat;
    $result = $settings->save();

当我第一次运行这些函数时(每个函数都是通过 ajax 调用独立运行的),我知道这是正确的:

然后,当我尝试更新 timeformat,(同样每个都是独立运行的)我得到这个:

由于某种原因,timezone 设置覆盖了timeformat 设置,我不知道为什么。

这是 UserSettingsModel 类:

class UserSettingsModel extends BaseModel
    protected $table      = 'user_settings';
    protected $fillable   = ['user_id', 'setting', 'value'];
    protected $primaryKey = 'user_id';
    public $timestamps    = false;

这是时区更新的查询日志:

array:2 [
  0 => array:3 [
    "query" => "select * from `user_settings` where (`user_id` = ? and `setting` = ?) limit 1"
    "bindings" => array:2 [
      0 => 1
      1 => "timezone"
    ]
    "time" => 0.27
  ]
  1 => array:3 [
    "query" => "update `user_settings` set `value` = ? where `user_id` = ?"
    "bindings" => array:2 [
      0 => "America/Chicago"
      1 => 1
    ]
    "time" => 19.73
  ]
]

这是 timeformat 查询的查询日志:

array:2 [
  0 => array:3 [
    "query" => "select * from `user_settings` where (`user_id` = ? and `setting` = ?) limit 1"
    "bindings" => array:2 [
      0 => 1
      1 => "timeformat"
    ]
    "time" => 0.25
  ]
  1 => array:3 [
    "query" => "update `user_settings` set `value` = ? where `user_id` = ?"
    "bindings" => array:2 [
      0 => "12hr"
      1 => 1
    ]
    "time" => 13.67
  ]
]

【问题讨论】:

不是 Laravel 专家...但我会检查进行 ajax 调用的代码。 它正在发送正确的数据,变量$timezone$timeformat在转储中有正确的数据。 laravel 代码似乎没有问题。 我看不出 laravel 代码有什么问题。如果你直接访问 url,它会做你想做的事吗? 我不能,因为它是PUT 类型 【参考方案1】:

您有一个由user_idsettings 组成的复合主键。

但是你的模型声明

    protected $primaryKey = 'user_id';

您发布的查询日志清楚地表明SELECT 语句是正确的,但UPDATE 不是因为WHERE 子句仅指定了user_id 的要求。

谷歌搜索(和其他人评论的那样)Laravel 似乎有复合键的问题。

如果您没有找到合适的解决方法,您可以在表中添加 id 列(主键、整数、自动增量)并更新模型定义。

然后让其他列成为标准列(如果需要,只需将它们编入索引即可)。

在添加新用户时,您将需要做一些额外的工作,因为我猜您想为每个 setting 添加一行...

【讨论】:

添加自动递增主键有效。然后,我将主复合键更改为唯一复合键。

以上是关于Laravel save() 正在更新错误的 mysql 记录的主要内容,如果未能解决你的问题,请参考以下文章

无法在模型对象 Laravel 上调用 SAVE 方法

PHP / Laravel - 更新 JSON 对象的值

Laravel/Ardent - 在 save() 上,错误:关系方法必须返回 Illuminate 类型的对象

Laravel - 调用未定义的方法 TrainingFacade::save()

在 Laravel 中的函数后 save() 出错

Windows 更新 1903 后 Composer 无法使用 laravel