带有连接表的Doctrine ManyToOne - 过滤结果

时间:2013-09-07 22:06:42

标签: sql symfony doctrine-orm sonata-admin sonata-user-bundle

我有一个Customer实体和User实体,其中有一个JOIN关系表customers_users

Customer实体中我有这个。

/**
 * @var User
 * 
 * @ORM\ManyToMany(targetEntity="Entity\User")
 * @ORM\JoinTable(name="customers_users",
 *     joinColumns={@ORM\JoinColumn(name="customer_id", referencedColumnName="id")},
 *     inverseJoinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id", unique=true)}
 * )
 * 
 */
private $users;

我希望在创建客户时我可以将用户分配给它并且实际上它运行良好,但是我希望过滤用户只显示那些没有分配给任何客户的用户。

例如,我有两个客户和两个用户,第一个客户分配了两个用户;然后,当我编辑第二个客户时,似乎有两个用户被分配给它,但是当我选择这些并且我发送表单时,它会抛出以下异常:

An exception occurred while executing 'INSERT INTO customers_users (customer_id, user_id) VALUES (?, ?)' with params [2, 1]:

SQLSTATE[23505]: Unique violation: 7 ERROR: duplicate key value violates unique constraint "uniq_2763c6cca76ed395"
DETAIL: Key (user_id)=(1) already exists.

2 个答案:

答案 0 :(得分:1)

/**
 * @var User
 * 
 * @ORM\ManyToMany(targetEntity="Entity\User", inversedBy="customers")
 * @ORM\JoinTable(name="customers_users",
 *     joinColumns={@ORM\JoinColumn(name="customer_id", referencedColumnName="id")},
 *     inverseJoinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id", unique=true)}
 * )
 * 
 */
private $users;

并且在User实体中,您应该在customers注释中添加:

 * @ORM\ManyToMany(targetEntity="Entity\Customer", inversedBy="users")
(...)

答案 1 :(得分:1)

我在这种情况下实际做的是:

// UserAdmin.php that extends SonataAdminBundle's User admin

/**
 * {@inheritdoc}
 */
public function createQuery($context = 'list')
{
    /** @var QueryBuilder $query */
    $query = parent::createQuery();

    $request = Request::createFromGlobals();

    // Could not find another way to detect that admin list is created from
    // sonata_type_model_list parent.
    // Of course, this applies only to sonata_type_model_list field type.

    if ($request->query->get('pcode') == 'demo.admin.customer') {
        $alias = $query->getRootAliases()[0];

        $query->leftJoin($alias . '.customers', 'c');
        // $query-> ... do filtering here
    }

    return $query;
}

这样我就可以以任何我想要的方式过滤用户。