使用自定义查询构建器的 ManyToMany 实体的 Symfony 表单

Symfony Form for ManyToMany Entity using a custom query builder

错误消息如下所示:

[Semantical Error] line 0, col 58 near 'events = :eventId': Error: Invalid PathExpression. StateFieldPathExpression or SingleValuedAssociationField expected.

这是正确的,因为它是一个 ManyToMany 连接,还有一个连接 table。但是我该如何加载这些实体?

问题出在 activity 表格(最后)。我尝试加载分配有 ManyToMany 的城镇加入特定事件。 代码说了1000多字,看一看(:

所以我在 Symfony 应用程序中有三个实体。 EventTownActivity

Event 看起来像这样:

// ...

/**
 * @var string
 *
 * @ORM\Column(name="name", type="string", length=255)
 * @Gedmo\Versioned
 */
private $name;

/**
 * @ORM\ManyToMany(targetEntity="Town", inversedBy="events")
 * @ORM\JoinTable(name="Events_to_Towns")
 **/
private $towns;

/**
 * @ORM\OneToMany(targetEntity="Activity", mappedBy="event")
 */
private $activitys;

// ...

Town 看起来像这样:

// ...

/**
 * @var string
 *
 * @ORM\Column(name="name", type="string", length=255)
 * @Gedmo\Versioned
 */
private $name;

/**
 * @ORM\ManyToMany(targetEntity="Event", mappedBy="towns")
 */
private $events;

/**
 * @ORM\OneToMany(targetEntity="Activity", mappedBy="town")
 */
private $activitys;

// ...

Activity 看起来像这样:

// ...

/**
 * @var string
 *
 * @ORM\Column(name="name", type="string", length=255)
 * @Gedmo\Versioned
 */
private $name;

/**
 * @ORM\ManyToOne(targetEntity="Town", inversedBy="activitys")
 * @ORM\JoinColumn(name="town_id", referencedColumnName="id")
 */
private $town;

/**
 * @ORM\ManyToOne(targetEntity="Event", inversedBy="activitys")
 * @ORM\JoinColumn(name="event_id", referencedColumnName="id")
 */
private $event;

// ...

一切正常。但是,当我想分配一个 Town 或多个时,问题出在 Activity 的表单中。我尝试只加载映射到事件的城镇。

// ...

public function __construct($eventId) {
    $this->_eventId = $eventId;
}

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $eventId = $this->_eventId;

    $builder
        // ...

        // this work's as expected!
        ->add('category', 'entity', array(
            'required'      => true,
            'label'         => 'Kategorie',
            'class'         => 'FooEventBundle:Category',
            'property'      => 'name',
            'query_builder' => function(\Foo\EventBundle\Entity\CategoryRepository $er) use ($eventId) {
                return $er->createQueryBuilder('c')
                    ->select('c')
                    ->where('c.event = :eventId')
                    ->setParameter('eventId', $eventId)
                ;
            }
        ))

        // here's the problem!
        ->add('town', 'entity', array(
            'required'      => true,
            'label'         => 'Stadt',
            'class'         => 'FooEventBundle:Town',
            'property'      => 'name',
            'query_builder' => function(\Foo\EventBundle\Entity\TownRepository $er) use ($eventId) {
                return $er->createQueryBuilder('t')
                    ->select('t')
                    ->where('t.events = :eventId')
                    ->setParameter('eventId', $eventId)
                ;
            }
        ))

        // ...

    ;
}

// ...

类似于:

            $er->createQueryBuilder('t')
            ->select('t')
            ->join('t.events', 'e')
            ->where('e.id = :eventId')
            ->setParameter('eventId', $eventId)

应该可以。