如何解决Laravel Backpack中MySQL虚拟生成列的插入报错问题
解决Laravel Backpack中MySQL虚拟生成列的插入报错问题
场景:MySQL表中通过
->virtualAs()定义了虚拟生成列type_subscr,在Laravel Backpack的CRUD控制器中给该字段添加了readonly属性防止用户修改,但创建新条目时SQL插入语句因包含该字段报错:Illuminate\Database\QueryException SQLSTATE[HY000]: General error: 3105 The value specified for generated column 'type_subscr' in table 'subscriptions' is not allowed.原因:前端
readonly仅限制用户输入,但表单仍会提交该字段的空值/默认值,Laravel将其纳入批量赋值,触发MySQL的生成列赋值限制。
方案一:模型层面处理(推荐,无需修改控制器)
在对应的Subscription模型中,通过批量赋值规则排除type_subscr字段:
- 如果使用
$guarded(指定不可批量赋值的字段):
class Subscription extends Model { protected $guarded = ['type_subscr']; // 其他模型代码... }
- 如果使用
$fillable(指定可批量赋值的字段),确保type_subscr不在列表中:
class Subscription extends Model { protected $fillable = [ 'supporter_id_from', 'supporter_id_to', 'transaction_id', 'date_start', 'date_end', 'notes' ]; // 其他模型代码... }
这样Laravel会自动在插入/更新时忽略该字段,不会出现在SQL语句中。
方案二:Backpack控制器层面处理
如果需要保留字段在表单中的只读显示,同时阻止其被提交到后端,可以在CRUD字段定义中添加ignore参数:
在控制器的setupCreateOperation()和setupUpdateOperation()方法里,修改字段配置:
$this->crud->addField([ 'name' => 'type_subscr', 'type' => 'text', 'attributes' => ['readonly' => 'readonly'], 'ignore' => true, // 关键:告知Backpack不将该字段纳入提交数据 ]);
或者,也可以手动在store()和update()方法中移除请求里的该字段:
public function store() { $this->crud->getRequest()->remove('type_subscr'); return parent::store(); } public function update() { $this->crud->getRequest()->remove('type_subscr'); return parent::update(); }
内容的提问来源于stack exchange,提问作者Andover Beacon
相关产品推荐
相关产品推荐

