Laravel Backpack关联字段自定义:实现角色名+用户名展示需求
问题背景
现有三个模型:User、Role、Service,关联关系为:Role 与 User 关联,User 与 Service 关联。在添加 Service 新条目时,需要关联 User,当前字段配置及 FetchOperation Trait 代码可正常运行,但需求调整为:关联选择框的搜索栏显示「角色名 | 用户名」格式(例如 admin | John),但关联属性仅存储用户名。
当前运行代码
字段配置
[ 'label' => 'User', 'type' => 'relationship', 'name' => 'users', 'entity' => 'users', 'attribute' => 'name', 'ajax' => true, 'minimum_input_length' => 0, ],
FetchOperation Trait 代码
public function fetchUsers() { return $this->fetch([ 'model' => Users::class, 'searchable_attributes' => ['name'], 'paginate' => 10, 'query' => function ($model) { $search = request()->input('q') ?? false; if ($search){ return $model->where('users.name', 'like', "%$search%"); }else{ return $model; } } ]); }
正确实现方案
步骤1:修改 fetchUsers 方法
调整查询逻辑,关联 Role 表并拼接显示文本,同时确保存储值为用户名:
public function fetchUsers() { return $this->fetch([ 'model' => Users::class, 'searchable_attributes' => [], // 禁用默认搜索,使用自定义查询 'paginate' => 10, 'query' => function ($model) { $search = request()->input('q') ?? ''; // 关联Role表(注意:根据实际表名/关联字段调整join条件) $query = $model->leftJoin('roles', 'users.role_id', '=', 'roles.id') ->selectRaw('users.name as value, CONCAT(roles.name, " | ", users.name) as display_name'); if ($search) { // 支持同时搜索角色名和用户名 $query->where(function ($q) use ($search) { $q->where('users.name', 'like', "%{$search}%") ->orWhere('roles.name', 'like', "%{$search}%"); }); } return $query; } ]); }
步骤2:调整字段配置
将 attribute 改为自定义的显示字段 display_name,确保选择框显示拼接后的文本:
[ 'label' => 'User', 'type' => 'relationship', 'name' => 'users', 'entity' => 'users', 'attribute' => 'display_name', // 对应查询中定义的显示字段 'ajax' => true, 'minimum_input_length' => 0, ],
关键说明
- 将
leftJoin移到外层,确保无论是否搜索都关联Role表,避免显示字段缺失。 - 通过
selectRaw明确指定:value为用户名(用于存储),display_name为拼接后的显示文本。 - 扩展搜索逻辑,支持同时匹配角色名和用户名,提升搜索体验。
内容的提问来源于stack exchange,提问作者KordDEM
相关产品推荐
相关产品推荐

