Sonata Admin如何复用现有QueryBuilder避免下拉已选值被覆盖
Sonata Admin 关联EntityType字段自定义筛选不影响回显的实现方案
问题原因
在configureFormFields中给EntityType字段配置query_builder时,直接通过Repository创建全新的QueryBuilder实例,会完全覆盖Sonata Admin内置的关联字段查询逻辑。内置逻辑默认会自动将当前已绑定的存量关联值加入查询结果集,保证编辑时已选值正常回显,覆盖后这部分逻辑失效,就会出现下拉框找不到已选值、回显失败的问题。
可用实现方案
方案一:复用关联Admin的内置QueryBuilder(推荐)
通过配置的admin_code拿到对应的User Admin服务,基于它已经构建好的QueryBuilder实例追加角色筛选条件,既保留所有内置逻辑(包括回显兼容、权限过滤、默认排序等),又能实现角色筛选需求,代码如下:
/** * @param FormMapper $formMapper */ public function configureFormFields(FormMapper $formMapper) { $formMapper ->add('sitter', EntityType::class, [ 'class' => User::class, 'query_builder' => function (EntityRepository $entityRepository) { // 拿到对应admin服务的内置查询构建器 $userAdmin = $this->getConfigurationPool()->getAdminByAdminCode('admin.user'); $queryBuilder = $userAdmin->createQuery(); $rootAlias = $queryBuilder->getRootAliases()[0]; // 仅追加角色筛选条件,不覆盖原有逻辑 return $queryBuilder ->andWhere(sprintf('%s.roles LIKE :staffRole', $rootAlias)) ->setParameter('staffRole', '%ROLE_STAFF%'); } ], ['admin_code' => 'admin.user']) ; }
方案二:手动兼容已选值(无Admin服务依赖)
如果不想耦合Admin服务的查询逻辑,可以在自己构建的QueryBuilder中追加OR条件,把当前编辑对象已经绑定的sitter值加入允许返回的结果集,同样可以解决回显问题:
/** * @param FormMapper $formMapper */ public function configureFormFields(FormMapper $formMapper) { $formMapper ->add('sitter', EntityType::class, [ 'class' => User::class, 'query_builder' => function (EntityRepository $entityRepository) { // 获取当前编辑对象已绑定的sitter ID $currentSitterId = $this->getSubject()?->getSitter()?->getId(); $qb = $entityRepository->createQueryBuilder('u'); // 筛选逻辑:要么是拥有ROLE_STAFF的用户,要么是当前已经绑定的存量值 $qb->andWhere( $qb->expr()->orX( $qb->expr()->like('u.roles', ':staffRole'), $qb->expr()->eq('u.id', ':currentSitterId') ) ) ->setParameter('staffRole', '%ROLE_STAFF%') ->setParameter('currentSitterId', $currentSitterId); return $qb; } ], ['admin_code' => 'admin.user']) ; }
方案选择建议
- 优先选方案一:和Sonata Admin的内置逻辑兼容度最高,会自动继承User Admin中已经配置的权限校验、默认排序、全局筛选等规则,后续如果User Admin调整查询逻辑不需要单独修改这里
- 仅当你希望这个字段的查询完全独立、不继承User Admin的其他查询规则时,再选择方案二
内容的提问来源于stack exchange,提问作者Deadpool
相关产品推荐
相关产品推荐

