Laravel获取数据库价格值异常:为何{"price":80}改用value后存为null?
问题分析与解决方案
首先咱们拆解一下你遇到的两个问题,再给出对应的解决办法:
为什么first(['rates.price'])会得到{"price":80}?
当你调用first(['rates.price'])时,Eloquent返回的不是单纯的数值,而是一个Booking模型实例——哪怕你只指定了一个字段,它依然会封装成模型对象。当你直接把这个模型赋值给$bookings->price时,Laravel会自动将模型序列化成JSON/数组格式,所以最终存储的就是{"price":80}这种对象结构,而非你需要的double类型数值。
为什么换成value('rates.price')会返回null?
大概率是查询条件的问题,常见的几个可能性:
- 用户ID字段错误:Laravel默认用户表的主键是
id,但你用了Auth::user()->userid,如果你的用户表主键不是userid,这个条件会直接导致查询无结果,进而value()返回null。 - 冗余条件导致无匹配:你加了
where('bookings.park_area','=',$bookings->park_area),如果$bookings是你正要保存的新模型(还没写入数据库),或者park_area值为空,这个条件会让查询找不到匹配的记录。 - 字段引用的小坑:虽然你写了
rates.price,但极少数情况下,Eloquent的value()方法在Join场景下可能对跨表字段的识别有问题,不过这个概率很低。
如何正确获取80这个数值?
给你三个可行的方案,按推荐程度排序:
方案1:从first()返回的模型中提取属性值
既然first()能拿到包含price的模型,直接提取属性值即可:
$duit = Booking::join('rates', 'bookings.park_area', '=', 'rates.areaid') ->where('bookings.user_id', '=', Auth::user()->id) // 这里改成id,除非你的用户主键确实是userid ->where('bookings.park_area', '=', $bookings->park_area) ->where('bookings.semester', '=', $bookings->semester) ->first(['rates.price']); if ($duit) { // 先判断是否存在结果,避免报错 $bookings->price = $duit->price; // 提取模型的price属性值 $bookings->save(); }
方案2:排查并修复value()的查询问题
先确保查询条件正确,再用value()直接取数值:
$price = Booking::join('rates', 'bookings.park_area', '=', 'rates.areaid') ->where('bookings.user_id', '=', Auth::user()->id) ->where('bookings.park_area', '=', $bookings->park_area) ->where('bookings.semester', '=', $bookings->semester) ->value('rates.price'); if ($price !== null) { $bookings->price = $price; $bookings->save(); }
如果还是返回null,建议打印实际执行的SQL排查问题:
$query = Booking::join('rates', 'bookings.park_area', '=', 'rates.areaid') ->where('bookings.user_id', '=', Auth::user()->id) ->where('bookings.park_area', '=', $bookings->park_area) ->where('bookings.semester', '=', $bookings->semester) ->select('rates.price'); dd($query->toSql(), $query->getBindings()); // 打印SQL语句和绑定参数,检查是否符合预期
方案3:用Eloquent关联(最优雅的长期方案)
既然Bookings和Rates通过park_area与areaid关联,直接在Booking模型中定义关联关系:
// 在Booking模型文件中 public function rate() { return $this->belongsTo(Rate::class, 'park_area', 'areaid'); }
然后直接通过关联获取价格:
// 确保$bookings已经有user_id、park_area、semester的有效值 $price = $bookings->rate->price ?? null; if ($price !== null) { $bookings->price = $price; $bookings->save(); }
这种方式更符合Laravel的设计理念,代码也更简洁易维护。
内容的提问来源于stack exchange,提问作者Izzat
相关产品推荐
相关产品推荐

