Laravel的save()方法正在更新错误的mysql记录。
Laravel的save()方法正在更新错误的mysql记录。
我有一个用户设置表,包含3列:user_id、setting和value。然后我有两个函数,一个用于保存时区,一个用于保存时间格式。\n当我第一次运行这两个函数(每个函数通过ajax调用独立运行)时,结果是正确的。然后当我尝试更新timeformat时,(同样是独立运行),却出现了问题。某种原因导致timezone设置覆盖了timeformat设置,我不确定为什么会这样。\n以下是UserSettingsModel类的代码:\nclass UserSettingsModel extends BaseModel{\n protected $table = \'user_settings\';\n protected $fillable = [\'user_id\', \'setting\', \'value\'];\n protected $primaryKey = \'user_id\';\n public $timestamps = false;\n}\n以下是时区更新的查询日志:\narray:2 [\n 0 => array:3 [\n \"query\" => \"select * from `user_settings` where (`user_id` = ? and `setting` = ?) limit 1\"\n \"bindings\" => array:2 [\n 0 => 1\n 1 => \"timezone\"\n ]\n \"time\" => 0.27\n ]\n 1 => array:3 [\n \"query\" => \"update `user_settings` set `value` = ? where `user_id` = ?\"\n \"bindings\" => array:2 [\n 0 => \"America/Chicago\"\n 1 => 1\n ]\n \"time\" => 19.73\n ]\n]\n以下是时间格式查询的查询日志:\narray:2 [\n 0 => array:3 [\n \"query\" => \"select * from `user_settings` where (`user_id` = ? and `setting` = ?) limit 1\"\n \"bindings\" => array:2 [\n 0 => 1\n 1 => \"timeformat\"\n ]\n \"time\" => 0.25\n ]\n 1 => array:3 [\n \"query\" => \"update `user_settings` set `value` = ? where `user_id` = ?\"\n \"bindings\" => array:2 [\n 0 => \"12hr\"\n 1 => 1\n ]\n \"time\" => 13.67\n ]\n]
问题出现的原因是,Laravel中的save()方法更新了错误的MySQL记录。这是由于模型中声明的复合主键与实际数据库表结构不一致导致的。模型中的$primaryKey属性指定了'user_id'作为主键,而实际上复合主键是由'user_id'和'settings'组成的。
解决方法是在数据库表中添加一个'id'列作为自增的主键,并更新模型定义。同时,将复合主键改为唯一的复合键。这样做后,在添加新用户时需要进行额外的工作,因为每个'setting'都需要添加一行记录。
以下是解决方法的代码示例:
// 数据库表结构 Schema::create('table_name', function (Blueprint $table) { $table->increments('id'); $table->integer('user_id'); $table->string('settings'); // 其他列... }); // 模型定义 class ModelName extends Model { protected $table = 'table_name'; protected $primaryKey = 'id'; // 其他属性和方法... } // 更新记录 $model = ModelName::where('user_id', $user_id) ->where('settings', $settings) ->first(); $model->column_name = $new_value; $model->save();
通过添加自增的主键,我们解决了Laravel save()方法更新错误记录的问题,并且通过将复合主键改为唯一复合键,保证了数据的唯一性。