Voyager Laravel中merge方法失效,lab_price无默认值报错如何解决
问题原因
- 你用的
insertUpdateData是Voyager框架内置的BREAD操作方法,它只会读取你在对应数据类型「添加字段」配置中开启的字段,即使你给Request合并了lab_price,只要这个字段没被加入到配置的可写字段列表,就会被方法自动过滤。 - 对应子表模型的
$fillable批量赋值属性没有包含lab_price,即使参数传递正确,ORM也会自动过滤掉该字段,导致写入时缺失值。
方案1:修改现有控制器逻辑
- 第一步:登录Voyager后台,进入对应数据类型的字段管理,新增
lab_price字段,设置字段类型为Hidden(不会在前端表单显示),勾选「可创建」「可编辑」权限。 - 第二步:修改控制器代码,删除
merge后多余的->all()调用(该调用只会返回参数数组,不会修改Request实例本身,属于无效代码),修改后代码如下:
$val = $this->validateBread($request->all(), $dataType->addRows)->validate(); $l_price = DB::table('labs') ->where('id', $request->lab_id) ->value('price'); $request->merge(['lab_price' => $l_price]); $data = $this->insertUpdateData($request, $slug, $dataType->addRows, new $dataType->model_name());
- 第三步:确认子表模型的
$fillable数组中已加入lab_price字段。
方案2:通过Observer实现(更推荐,解耦业务逻辑)
Observer完全支持关联查询,只需要在模型的创建/更新事件触发前自动赋值即可,不需要修改控制器代码,实现步骤如下:
- 生成对应子表模型的Observer,执行命令:
php artisan make:Observer LabSubModelObserver --model=LabSubModel
(将LabSubModel替换为你实际的子表模型类名) - 编辑生成的Observer文件,写入赋值逻辑:
<?php namespace App\Observers; use App\Models\LabSubModel; use Illuminate\Support\Facades\DB; class LabSubModelObserver { // 模型创建前触发 public function creating(LabSubModel $model): void { $model->lab_price = DB::table('labs') ->where('id', $model->lab_id) ->value('price'); } // 模型更新前触发,仅lab_id变更时同步更新价格 public function updating(LabSubModel $model): void { if ($model->isDirty('lab_id')) { $model->lab_price = DB::table('labs') ->where('id', $model->lab_id) ->value('price'); } } }
- 注册Observer,打开
app/Providers/EventServiceProvider.php,在$observers属性中添加注册配置:
protected $observers = [ \App\Models\LabSubModel::class => \App\Observers\LabSubModelObserver::class, ];
- 确认子表模型的
$fillable数组中已加入lab_price字段即可。
内容的提问来源于stack exchange,提问作者Zia Khan
相关产品推荐
相关产品推荐

