在ManyToMany关系中使用Artist和Show的实体,尝试构建一个列出现有艺术家尚未在给定节目中的表单会导致错误
错误:无效的PathExpression。必须是 CollectionValuedAssociationField
在Doctrine's documentation处有notIn($x, $y)
表达式,但它完全没有明确(即尝试失败)如何在表单类中使用它。
可以在Artist Repository中获得预期结果,其功能如下所示。但是它在表单类中不可用,因为它的结果不是QueryBuilder的实例! [感谢xurshid29' s SO answer。]
public function notInShow($show)
{
$qb = $this->getEntityManager()->createQueryBuilder();
$ids = $qb
->select('a.id')
->from('AppBundle:Artist', 'a', 'a.id')
->leftJoin('a.shows', 's')
->where('s.show = ?1')
->setParameter(1, $show->getShow())
->getQuery()
->getArrayResult();
$ids = array_keys($ids);
$qbA = $this->getEntityManager()->createQuery(
'SELECT a FROM AppBundle:Artist a '
. 'WHERE a.id NOT IN (:ids)')
->setParameter(':ids', $ids)
->getResult();
return $qbA;
}
构建字段的最新尝试(很多)如下所示:
表单类(代码段):
public function buildForm(FormBuilderInterface $builder, array $options)
{
$show = $options['show'];
$builder->add('artists', EntityType::class,
[
'class' => Artist::class,
'choice_label' => function($artist, $key, $index) {
return $artist->getLastName() . ', ' . $artist->getFirstName();
},
'query_builder' => function (EntityRepository $er) use($show) {
return $er->createQueryBuilder('a')
->join('a.shows', 's')
->where('a NOT MEMBER of s')
->andWhere('IDENTITY(s) = :show')
->setParameter(':show', $show->getId())
->orderBy('a.firstName', 'ASC')
->orderBy('a.lastName', 'ASC')
;
},
'expanded' => true,
'multiple' => true,
]);
}
实体摘录:
艺术家:
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="Show", mappedBy="artists")
*/
protected $shows;
显示:
/**
* @var \Doctrine\Common\Collections\Collection
*
* @ORM\ManyToMany(targetEntity="Artist", inversedBy="shows", cascade={"persist"})
* @ORM\JoinTable(name="participation",
* joinColumns={@ORM\JoinColumn(name="show_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="artist_id", referencedColumnName="id")}
* ))
*/
protected $artists;
答案 0 :(得分:0)
最后!最后的一些调整,这是有效的:
public function buildForm(FormBuilderInterface $builder, array $options)
{
$show = $options['show'];
$builder->add('artists', EntityType::class,
[
'class' => Artist::class,
'choice_label' => function($artist, $key, $index) {
return $artist->getLastName() . ', ' . $artist->getFirstName();
},
'query_builder' => function (EntityRepository $er) use($show) {
$qb = $er->createQueryBuilder('a');
$ids = $qb
->select('a.id')
->leftJoin('a.shows', 's')
->where('s.show = ?1')
->setParameter(1, $show->getShow())
->getQuery()
->getResult();
if (empty($ids)) {
return $er->createQueryBuilder('a');
} else {
return $er->createQueryBuilder('a')
->where($er->createQueryBuilder('a')->expr()->notIn('a.id', ':ids'))
->setParameter(':ids', $ids);
}
},
'expanded' => true,
'multiple' => true,
])
->add('save', SubmitType::class,
array(
'label' => 'Add artist(s)',
'label_format' => ['class' => 'text-bold']
));
}