提问者:小点点

如何在Twig模板中使用自定义存储库方法?


假设我有一个实体User和一个实体Book,它们都由User.bookId=Book.id连接(这标志着用户拥有某本书,关系类型oneUserToManyBook)...

如果我现在想用Doctrine的DQL或QueryBuilder为用户阅读的所有书籍执行性能友好的获取,那么在Symfony2/Doctrine2 webapp中实现这一点的最佳方法是什么,以便我可以在Twig模板中的用户循环中使用它们?

{% for user in users %}
   {{ user.name|e }}
       {% for address in user.getAddressesByUserId(user.getId()) %}
           {{ address.city }}
       {% endfor %}
{% endfor %}

我看到两种方法,但都无法实现我的目标:

创建自定义存储库类BookRepository

public function getBooksOwnedByUser($user_id) {
    return $em->createQuery('SELECT b.title
                             FROM MyBundle\Entity\User u,
                                  MyBundle\Entity\Book b
                             WHERE u.book_id = b.id'
                             AND u.id = :user_id)
              ->setParameter('user_id', $user_id)
              ->getResult();
}

问题:工作正常,但我无法在我的Twig模板中调用GetBookOwnedByUser()(因为它不绑定到实体User,而是绑定到它的存储库,它是Doctrine\ORM\EntityRepository的子类。

执行与上面相同的查询-不在myUserRepository中执行,而是直接在myUser实体类中执行。

这里的问题是:我可以在我的Twig模板中调用此方法,但我不能(也不应该)在我的User实体类中使用EntityManager


共1个答案

匿名用户

最好是建立从用户到图书的关系。假设你已经建立了这种关系,你可以这样查询:

public function getBooksOwnedByUser($user_id) {
    return $em->createQuery('SELECT u, b
                            FROM MyBundle\Entity\User u
                            JOIN u.books b
                            WHERE  u.id = :user_id')
                        ->setParameter('user_id', $user_id)
                        ->getResult();
}

然后在你的控制器中:

$em = $this->getDoctrine()->getManager();
$user_with_books = $em->getRepository('MyBundle\Entity\User')
    ->getBooksOwnedByUser($user->getId());

return $this->render('YourTemplate.html.twig', array(
        'user_with_books' => $user_with_books,
));

细枝:

{% for book in user.books %}
    {{ book.title }}
{% endfor %}

一些考虑:

  1. 对于多个用户,您将不得不更改查询(延迟加载是可能的,但不建议)。
  2. 如果它是大量的数据,您可以通过获得标量结果(数组)来提高性能
  3. 如果你需要不同的用户查询,不能组合,你将不得不存储不同的变量(对象或数组)。这就是为什么我把它命名为“user_with_books”。但是如果你的模板中只有这个用户,你也可以称之为“用户”。
  4. user.get地址ByUserId(user.getId())

因此答案是:您不能使用自定义存储库方法做任何事情,因为它是一个函数。函数本身并不表示任何数据。因此,这是一种使用该函数检索实际数据并显示数据的方法。