【问题标题】:Filter collection in Symfony formtypeSymfony 表单类型中的过滤器集合
【发布时间】:2017-04-10 19:12:09
【问题描述】:

总结

我有三个实体: 用户、组织和组织用户。

我创建了一个包含 OrganisationUser 的嵌入式集合的组织表单。这是有效的。我无法开始工作的是,只有没有关联(组织)的用户会被“查询”并显示在 OrganisationForm 的选择框中。

详情

实体 1:组织

class Organisation
{

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;

    /**
     *
     * @ORM\Column(type="string", nullable=true)
     */
    protected $name;


    /**
     * @ORM\OneToMany(targetEntity="OrganisationUser", mappedBy="organisation_id", cascade={"persist", "remove"}, orphanRemoval=true)
     *
     * @Expose
     */
    private $users;

实体 2:用户 (我扩展了 FOSUserBundle)

<?php


/**
 * @ORM\Entity(repositoryClass="AppBundle\Repository\UserRepository")
 * @ORM\Table(name="fos_user")
 */
class User extends BaseUser
{

    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;


    /**
     * @var string
     */
    protected $username;

    /**
     * @var \Doctrine\Common\Collections\ArrayCollection
     * @ORM\OneToMany(targetEntity="OrganisationUser", mappedBy="user_id", cascade={"ALL"}, orphanRemoval=true)
     */
    protected $organisationusers;

我已成功嵌入了一组表单。在我的“create-new-organisation-form”中,我可以添加许多用户,并将它们保存到数据库中。

它们保存在 OrganisationUser 表中(因为我只想将现有用户与组织相关联)。

OrganisationUser 实体(实际上我有三个实体)如下所示:

实体 3:OrganizationUser

<?php


class OrganisationUser
{

    protected $id;


    /**
     * @var ProjectId
     * @ORM\ManyToOne(targetEntity="Organisation", inversedBy="organisationusers")
     * @ORM\JoinColumn(name="organisation_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $organisation_id;


    /**
     * @var ProjectId
     * @ORM\ManyToOne(targetEntity="User", inversedBy="organisationusers")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id", onDelete="CASCADE")
     */
    protected $user_id;

现在,在我的表单 (OrgansionType) 中,我嵌入了一个 OrganisationUser 的集合。但我想操纵数据(我不想显示所有用户。只显示与组织无关的用户)。我怎样才能做到这一点。我已经在这里和这里看过了,但这不是这个问题的解决方案,所以我创建了一个新问题。

组织类型:

<?php

class OrganisationType extends AbstractType
{
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {


        $builder
            ->add('name')
            ->add('address')
            ->add('postal')
            ->add('city')
            ->add('phone')
            ->add('email')
            ->add('role');

        $builder->add('users', 'collection', array(
            'entry_type' => new OrganisationUserType(),
            'allow_add' => true,
            'allow_delete' => true,
            'by_reference' => false,
            'required' => false,
        ));


    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\Organisation',
        ));
    }
}

还有 OrganisationUserType:

<?php

class OrganisationUserType extends AbstractType
{

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder
            ->add('user_id', null ,array(
                'label' => 'User'
            ))
        ;
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\OrganisationUser'
        ));
    }

}

控制器

<?php

/**
 * Organisation controller.
 *
 * @Route("/organisation")
 */
class OrganisationController extends Controller
{    
    /**
     * Creates a new Organisation entity.
     *
     * @Route("/new", name="organisation_new")
     * @Method({"GET", "POST"})
     */
    public function newAction(Request $request)
    {
        $organisation = new Organisation();
        $form = $this->createForm('AppBundle\Form\OrganisationType', $organisation);

        $form->handleRequest($request);

        if ($form->isSubmitted() && $form->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($organisation);
            $em->flush();

            return $this->redirectToRoute('organisation_show', array('id' => $organisation->getId()));
        }

        return $this->render('organisation/new.html.twig', array(
            'organisation' => $organisation,
            'form' => $form->createView(),
        ));
    }

这是渲染时的样子: 而且,假设 testuser3 已经与我不希望他出现在下拉列表中的组织相关联:)

【问题讨论】:

  • 在您的控制器中,您可能在 editAction 中为表单加载数据。这可能是来自 te Doctrine::Repository 类的标准方法,例如 find($id)。您应该将其更改为自定义方法,该方法使用带有限制连接子句的自定义查询,如示例docs.doctrine-project.org/projects/doctrine-orm/en/latest/…(向下滚动一点)
  • 我转储了我的表单变量,但我没有在我的表单中看到任何用户。我编辑了我的问题并添加了控制器。顺便说一句,我也希望在 newAction 中这样做。

标签: forms symfony doctrine


【解决方案1】:

好的,我找到了。在我的 OrganisationType 中,我使用 OrganisationUserType 来嵌入用户集合。所以在 OrganisationUserType 我必须查询结果: 当然,这不是正确的查询,但我现在知道在哪里操作数据。现在我可以去搜索正确的查询了:)

<?php

namespace AppBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Doctrine\ORM\EntityRepository;

class OrganisationUserType extends AbstractType
{

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder
            ->add('user_id', 'entity', array(
                'class' => 'AppBundle:User',
                'query_builder' => function (EntityRepository $er) {
                    return $er->createQueryBuilder('u')
                        ->where('u.id > :id')
                        ->setParameter('id', '1')
                        ->orderBy('u.username', 'ASC');
                },
                'choice_label' => 'username',
                'required' => false,
            ));
    }

    /**
     * @param OptionsResolver $resolver
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\OrganisationUser',
        ));
    }

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-14
    • 1970-01-01
    • 1970-01-01
    • 2011-04-09
    • 1970-01-01
    • 1970-01-01
    • 2021-10-08
    相关资源
    最近更新 更多