Laravel Eloquent中conversion_rate字段无法更新的问题求助
问题排查与解决方案
我来帮你捋捋这个问题,之前我处理过类似的场景,大概率是Laravel的批量赋值保护机制在起作用,咱们一步步拆解:
1. 最核心的原因:模型未将conversion_rate加入批量赋值白名单
Laravel Eloquent默认开启了批量赋值保护,只有在模型的$fillable数组里声明的字段,才能通过update()、create()这类批量赋值方法修改。你提到iso字段能正常更新,基本可以确定它在$fillable里,但conversion_rate被遗漏了。
解决方法:
打开你的Currency模型,确保$fillable包含这两个字段:
class Currency extends Model { // 只允许批量赋值这些字段 protected $fillable = ['iso', 'conversion_rate']; }
2. 优化业务代码(顺便解决潜在性能问题)
你当前的写法存在两个没必要的性能损耗:
Currency::all()->contains('iso', $currency['iso_code'])会把整个currencies表的数据加载到内存中再做判断,数据量大时会拖慢程序where("iso", $currency['iso_code'])->get()->first()可以简化成where("iso", $currency['iso_code'])->first(),不需要先获取整个集合再取第一个模型
优化后的代码:
$feed = simplexml_load_file($url, LIBXML_NOCDATA); foreach ($feed->list->currency as $currency) { // 直接查找对应货币,存在则更新 $currencyModel = Currency::where('iso', $currency['iso_code'])->first(); if ($currencyModel) { // 批量赋值更新(需要fillable包含字段) $currencyModel->update(['conversion_rate' => 2.00]); // 或者用单字段赋值+保存,这种写法不受fillable限制(更适合单个字段更新) // $currencyModel->conversion_rate = 2.00; // $currencyModel->save(); } }
3. 额外排查点(如果上述方法无效)
如果还是无法更新,可以从这几个方向排查:
- 检查是否有模型观察者(Observer)或者全局作用域,拦截了
conversion_rate字段的更新操作 - 确认数据库表的
conversion_rate字段是否有特殊约束(比如只读、默认值锁死等),不过从你的表结构看应该没问题 - 开启Laravel查询日志,查看实际执行的SQL语句,确认更新语句是否包含
conversion_rate:
// 在代码开头添加 DB::enableQueryLog(); // ...你的业务代码... // 打印执行的所有SQL dd(DB::getQueryLog());
如果日志里的UPDATE语句没有conversion_rate,那还是批量赋值的问题;如果有,但数据库没更新,就需要检查数据库层面的约束了。
内容的提问来源于stack exchange,提问作者Tom Van Eerdt
相关产品推荐
相关产品推荐

