Laravel代码预填充数据库字段最佳方案?适配自定义值初始填充场景
嘿,针对你的车辆零售价值调整场景,我来分享几个Laravel里预填充JSON调整字段的最佳实践,完全贴合你的需求:
1. 先把数据库结构搭对
首先你的vehicles表得有原始值字段和存调整信息的JSON字段,写迁移的时候这么搞:
Schema::create('vehicles', function (Blueprint $table) { $table->id(); $table->decimal('retail_value', 10, 2); // 原始零售价值 $table->json('adjustments')->nullable(); // 存调整值+方案名称的JSON字段 $table->timestamps(); });
记得在Vehicle模型里加个$casts,让Laravel自动帮你转数组和JSON,省得手动编码解码:
protected $casts = [ 'adjustments' => 'array', 'retail_value' => 'decimal:2', ];
2. 新增数据时自动预填充
用Laravel的模型creating事件,只要新增车辆,自动把调整值设为原始值,方案名称默认给个"初始方案",在模型的booted方法里加:
protected static function booted() { static::creating(function ($vehicle) { // 直接给数组就行,$casts会自动转成JSON存在数据库里 $vehicle->adjustments = [ 'value' => $vehicle->retail_value, 'plan_name' => '初始方案' ]; }); }
这样用户新增车辆的时候,调整列就默认和原始值一致,不用手动输入。
3. 已有数据批量初始化
如果数据库里已经有一堆车辆数据没填调整值,别手动改,写个Artisan命令批量处理最方便:
先创建命令:
php artisan make:command InitializeVehicleAdjustments
然后在命令的handle方法里写逻辑:
public function handle() { // 只处理还没设置调整值的车辆 \App\Models\Vehicle::whereNull('adjustments')->each(function ($vehicle) { $vehicle->update([ 'adjustments' => [ 'value' => $vehicle->retail_value, 'plan_name' => '初始方案' ] ]); }); $this->info('搞定!所有车辆的调整值都初始化为原始值了~'); }
别忘了给命令加个签名,比如在命令类里:
protected $signature = 'vehicle:init-adjustments';
然后跑命令就行:
php artisan vehicle:init-adjustments
要是数据特别多,用数据库原生函数更快,直接在Tinker里执行:
\App\Models\Vehicle::whereNull('adjustments')->update([ 'adjustments' => \DB::raw("JSON_OBJECT('value', retail_value, 'plan_name', '初始方案')") ]);
4. 小优化:加个访问器方便取值
在视图里要拿调整后的值,每次都$vehicle->adjustments['value']太麻烦,加个访问器:
public function getAdjustedValueAttribute() { // 万一调整值为空,直接返回原始值兜底 return $this->adjustments['value'] ?? $this->retail_value; }
之后在视图里直接用$vehicle->adjusted_value就能拿到当前的调整值,省心。
5. 总和计算的小技巧
要算原始值总和和调整值总和,用集合或者数据库查询都可以:
// 原始值总和,直接用sum就行 $originalTotal = \App\Models\Vehicle::sum('retail_value'); // 调整值总和,用集合处理(数据量小的时候用) $adjustedTotal = \App\Models\Vehicle::get()->sum(fn($v) => $v->adjusted_value); // 数据量大的话,用数据库原生查询更高效 $adjustedTotal = \App\Models\Vehicle::selectRaw('SUM(JSON_UNQUOTE(JSON_EXTRACT(adjustments, "$.value"))) as total') ->value('total');
这些方法都是项目里实际用过的,完全适配你的业务场景,放心用~
内容的提问来源于stack exchange,提问作者Hondaman900
相关产品推荐
相关产品推荐

