Laravel Backpack 6:为带访问器的子字段关联添加自定义查询条件
问题:Laravel Backpack 6 关联子字段使用访问器属性时的筛选与显示异常
- 在CentreCrudController的Allocation子字段中,为User关联添加
active()scope筛选,同时想用访问器reverse_full_name作为下拉标签 - 直接用访问器做attribute时,MySQL报错
Unknown column 'reverse_full_name' in 'field list' - 用
DB::raw拼接字段别名后,筛选生效,但下拉仅显示ID,标签为空;换成last_name作为attribute则正常 - 尝试Ajax获取数据也无结果,换
last_name可正常返回
解决方案
核心问题是Backpack关联子字段在处理查询构造器返回结果时,对模型实例访问器的依赖逻辑被手动字段查询破坏。以下两种方案可解决:
方案一:保留模型实例,依赖访问器生成标签
不要用select()手动指定字段(避免覆盖默认模型字段选取逻辑),直接用orderByRaw实现排序,依赖模型的访问器提供下拉标签:
'options' => function ($query) { return $query->active() ->orderByRaw("concat(last_name, ' ', first_name) asc"); }, 'attribute' => 'reverse_full_name'
此方式不会破坏模型的属性加载流程,访问器reverse_full_name能正常被Backpack调用生成标签。
方案二:直接返回键值对数组
如果需要手动控制查询字段,可直接返回键值对数组,跳过模型实例的属性解析环节:
'options' => function () { return User::active() ->orderByRaw("concat(last_name, ' ', first_name) asc") ->pluck(DB::raw("concat(last_name, ' ', first_name)"), 'id') ->toArray(); }, // 无需指定attribute,因为已直接返回键值对
关键注意点
- 避免在
options的查询中使用select('users.*', DB::raw(...)),这会导致Backpack无法识别模型的访问器(查询返回的是自定义字段而非完整模型实例) - 模型中
$appends已包含reverse_full_name,确保访问器能被自动加载,无需额外配置
修改后的CentreCrudController代码示例
// app/Http/Controllers/Admin/CentreCrudController.php class CentreCrudController extends CrudController { protected function setupCreateOperation() { CRUD::field('allocations') ->type('relationship') ->subfields([ [ 'name' => 'user', 'options' => function ($query) { return $query->active() ->orderByRaw("concat(last_name, ' ', first_name) asc"); }, 'attribute' => 'reverse_full_name' ], [ 'name' => 'valid_date', 'type' => 'date' ], ]); } }
内容的提问来源于stack exchange,提问作者Bluebox
相关产品推荐
相关产品推荐

