You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 16:04:04