Symfony 表单 query_buider 和实体存储库

Posted

技术标签:

【中文标题】Symfony 表单 query_buider 和实体存储库【英文标题】:Symfony form query_buider and entity repository 【发布时间】:2013-07-14 15:32:30 【问题描述】:

我正在尝试根据正在登录的用户创建一个包含集合类型数据的表单。我正在关注this chapter of the Symfony cookbook。

query_builder 选项是我从 DQL 获取数据的闭包时,一切正常。由于需要从代码中的不同位置获取数据,我更愿意在 Repository 类中定义查询。

这是我存储库中的函数:

public function findOwnedBy($user) 
    $query = $this->getEntityManager()->createQuery("SELECT l FROM MyBundle:Article a JOIN a.owndBy u WHERE u.id = :userId");
    $query->setParameters(array("userId"=>$user->getId()));
    return $query->getResult();

这个函数在 Controller 中调用并返回一个 Article 数组时起作用。这是 symfony 文档的 sn-p :

$formOptions = array(
                    'class' => 'Acme\DemoBundle\Entity\User',
                    'multiple' => false,
                    'expanded' => false,
                    'property' => 'fullName',
                    'query_builder' => function(EntityRepository $er) use ($user) 
                        // build a custom query, or call a method on your repository (even better!)
                    ,
                );

当我在 query_builder 中调用我的 Repository 函数时,我收到一个错误:Expected argument of type "Doctrine\ORM\QueryBuilder", "array" given,我可以理解这是因为我的 Repository 返回的是一个实体数组,而不是一个 QueryBuilder。

我不想复制代码并在表单中创建新的 QueryBuilder。使用来自 Repository 的查询的最佳做法是什么?我正在考虑在存储库中有两个函数,一个返回一个数组,另一个返回 QueryBuilder,但是 Symfony 文档中的注释“或者在你的存储库上调用一个方法(更好!)”让我认为这种情况有更好的方法。

【问题讨论】:

【参考方案1】:

应该很容易。执行以下操作:

public function queryOwnedBy($user) 

    $query = $this->createQueryBuilder('a')
            ->from('MyBundle:Article', 'a')
            ->innerJoin('a.owndBy', 'u')
            ->where('u.id = :id')                
            ->setParameter('id', $user->getId());

    return $query;


public function findOwnedBy($user) 
    return $this->queryOwnedBy($user)
            ->getQuery()
            ->getResult();

然后在表单构建器中:

$formOptions = array(
    'class' => 'Acme\DemoBundle\Entity\User',
    'multiple' => false,
    'expanded' => false,
    'property' => 'fullName',
    'query_builder' => function(EntityRepository $er) use ($user) 
        return $er->queryOwnedBy($user);
    ,
);

编辑

感谢 ncatnow 和 unagi 我已更改以前的函数以返回查询构建器

【讨论】:

我也觉得应该很简单,这是我的第一次尝试。这将返回错误Expected argument of type "Doctrine\ORM\QueryBuilder", "array" given。似乎query_builder 期望一个 QueryBuilder 对象,无论它是直接给出还是由闭包返回。 编辑了帖子。创建两个函数,一个返回查询,另一个返回结果。在表单构建器上调用返回查询的函数。这应该工作,仍然是干燥的。对不起,我会更改名称,因为它们不合适。 呵呵,这确实是我所做的,也是我在问题最后一段中描述的。我会那样做,Symfony 文档中的小评论让我们认为它可以开箱即用,这很令人困惑;) @Florent 是的,抱歉,没有注意到最后一段需要注意。 请注意,上面的示例代码仍然不正确 - 它返回的是 Query 而不是 QueryBuilder 并且会失败。【参考方案2】:

我只是对 saamorim 的回答做了一点修正。工作代码是这样的:

public function queryOwnedBy($user) 

    $query = $this->createQueryBuilder("u")
            ->where('u.id = :id')                
            ->setParameter('id', $user->getId());

    return $query;


public function findOwnedBy($user) 
    return $this->queryOwnedBy($user)
            ->getQuery()
            ->getResult();

【讨论】:

谢谢。我已将您的答案整合到我的帖子中,并将查询更改为根据示例。

以上是关于Symfony 表单 query_buider 和实体存储库的主要内容,如果未能解决你的问题,请参考以下文章

Symfony 表单和 Ajax

枚举和 Symfony 表单的教义集合

如何使用 Symfony 表单和数据转换器实现测试隔离?

Symfony2 防止多个表单提交

Symfony2 表单和 <input> 模式属性

symfony2 构建表单实体 oneToMany