Symfony2如何使用querybuilder加入多对多关系?

时间:2012-08-18 08:52:38

标签: php symfony doctrine

作为symfony2和querybuilder的新手,我试图选择所有容器,但只将结果限制为登录用户可以访问的容器。

使用当前代码我收到此错误:

注意:未定义的索引:/var/www/biztv_symfony/vendor/doctrine/lib/Doctrine/ORM/Query/SqlWalker.php第746行中的容器

以下是我对查询的尝试(我已经尝试过这个和其他论坛网站的几个选项,但似乎仍然无法理解...)

public function indexAction()
{
    //Get the requisits        
    $companyId = $this->container->get('security.context')->getToken()->getUser()->getCompany()->getId();
    $em = $this->getDoctrine()->getEntityManager();

    //Fetch the containers
    $repository = $this->getDoctrine()->getRepository('BizTVContainerManagementBundle:Container');
    $query = $repository->createQueryBuilder('c')
        ->innerJoin('c.users','u')
        ->where('c.company = :company')
        ->setParameter('company', $companyId)
        ->orderBy('c.name', 'ASC')
        ->getQuery();
    $containers = $query->getResult();

我通过多对多关系跟踪访问,这是我的用户实体......

<?php
// src/BizTV/UserBundle/Entity/User.php

namespace BizTV\UserBundle\Entity;

use FOS\UserBundle\Entity\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;

use BizTV\BackendBundle\Entity\company as company;

/**
 * @ORM\Entity
 * @ORM\Table(name="fos_user")
 */
class User extends BaseUser
{
    /**
     * @ORM\Id
     * @ORM\Column(type="integer")
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    protected $id;  

    /**
    * @var object BizTV\BackendBundle\Entity\company
    *  
    * @ORM\ManyToOne(targetEntity="BizTV\BackendBundle\Entity\company")
    * @ORM\JoinColumn(name="company", referencedColumnName="id", nullable=false)
    */
    protected $company; 

    /**
     * @ORM\ManyToMany(targetEntity="BizTV\ContainerManagementBundle\Entity\Container", inversedBy="User")
     * @ORM\JoinTable(name="access")
     */
    private $access;

    public function __construct()
    {
        parent::__construct();

        $this->access = new \Doctrine\Common\Collections\ArrayCollection();

    }
//getters and setters...

这是我的容器实体:

<?php

namespace BizTV\ContainerManagementBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;

use BizTV\UserBundle\Entity\User as user;

/**
 * BizTV\ContainerManagementBundle\Entity\Container
 *
 * @ORM\Table(name="container")
 * @ORM\Entity
 */
class Container
{

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

    /**
     * @var string $name
     * @Assert\NotBlank(message = "Du måste ange ett namn för området") 
     * @ORM\Column(name="name", type="string", length=255)
     */
    private $name;
    //TODO: form handler assuring no name is used twice in same company

    /**
    * @var object BizTV\BackendBundle\Entity\company
    *  
    * @ORM\ManyToOne(targetEntity="BizTV\BackendBundle\Entity\company")
    * @ORM\JoinColumn(name="company", referencedColumnName="id", nullable=false)
    */
    protected $company; 

    /**
     * @ORM\ManyToMany(targetEntity="BizTV\UserBundle\Entity\User", mappedBy="Container")
     */
    private $users;

    public function __construct() {
        $this->users = new \Doctrine\Common\Collections\ArrayCollection();
    }

1 个答案:

答案 0 :(得分:3)

Container实体中,当您指定$users属性映射时,mappedBy的值很重要:您需要指定名称 User类中的反向属性。

在这里,我们有Container::$users&lt; - &gt; User::$access

将注释更改为:

class User
{
    /**
     * @ORM\ManyToMany(targetEntity="BizTV\ContainerManagementBundle\Entity\Container", inversedBy="users")
     * @ORM\JoinTable(name="access")
     */
    private $access;
}

class Container
{
    /**
     * @ORM\ManyToMany(targetEntity="BizTV\UserBundle\Entity\User", mappedBy="access")
     */
    private $users;
}

我建议您阅读doctrine orm documentation part about associations,并在所有关联中验证并解决此问题。