如何在Twig模板中使用自定义存储库方法? [英] How to use custom repository methods in Twig template?

查看:98
本文介绍了如何在Twig模板中使用自定义存储库方法?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一个实体用户和一个实体 Book ,它们都加入了$ code> User.bookId = Book.id (这标志着用户拥有某本书,关系类型为oneUserToManyBook)。



如果我现在想使用Doctrine的DQL或QueryBuilder对所有图书执行性能友好的提取 a 用户已阅读,最好的方法在Symfony2 / Doctrine2 webapp中实现这一点,以便我可以在Twig模板中的 User 循环中使用它们。



Twig



  {%用户%} 
{{user.name | e}}
{%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模板中的getBooksOwnedByUser()(因为它不绑定到实体 User ,而是它的存储库, Doctrine\ORM\EntityRepository 的子类






第二种方法



执行与上述相同的查询 - 不在我的 UserRepository 中,但直接在我的用户实体类。



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

解决方案

最好的,如果你从用户到书籍之间建立关系,假设你已经建立了这种关系,你可以这样查询:

  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,
));

在twig:

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

一些注意事项:


  1. 对于多个用户,您将不得不更改查询(懒加载是可能的,但不建议)。

  2. 如果数据很多,可以通过获得标量结果来获得性能提升(Array)

  3. 如果您对不能组合的用户需要不同的查询,则必须存储不同的变量(对象或数组)。这就是为什么我把它命名为user_with_books。但是,如果您只在模板中使用此用户,您可以将其称为用户。

  4. user.getAddressesByUserId(user.getId())< - 将数据从一个模型传递到查询是控制器(或服务)的责任。最好的做法是避免在你的模板中这样做。

所以答案:
你不能做任何事情,存储库方法,因为它是一个功能。本身的功能不代表任何数据。所以这是一种方法,您可以使用检索实际数据并显示该功能。


Assuming I have an entity User and an entity Book and they're both joined by User.bookId = Book.id (this marks a user owns a certain book, relation type oneUserToManyBook).

If I now want to execute a performance friendly fetch with Doctrine's DQL or QueryBuilder for all Books a User has read, what is the best way to implement this in a Symfony2/Doctrine2 webapp, so that I can use them in my User loop in a Twig template?

Twig

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


I see two approaches, but both don't lead to my target:

1st approach

Create a custom repository class 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();
}

Problem: Works fine, but I cant call getBooksOwnedByUser() in my Twig template (because it's not tied to the entity User, but to it's repository, which is a subclass of Doctrine\ORM\EntityRepository.


2nd approach

Execute the same query as above - not in my UserRepository, but directly in my User entity class.

Problem here: I could call this method in my Twig template, but I cannot (and should not) use the EntityManager in my User entity class.

解决方案

It's best if you make a relationship from User to Books. Assuming you have made this relationship you can make your query like this:

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();
}

Then in your controller:

$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,
));

In twig:

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

Some considerations:

  1. For multiple users you will have to change the query (lazy loading is possible but not advised).
  2. If it's a lot of data you can get a performance boost by getting a scalar result (Array)
  3. If you need different queries for the user that can not be combined you will have to store different variables (objects or arrays). That's why I named it "user_with_books". But if you only have this user in your template you can just as well call it "user".
  4. user.getAddressesByUserId(user.getId()) <-- passing data from one model to query is the responsiblity of the controller (or a service). Best practice is to avoid doing this in your template.

So the answer: You can not do anything with a custom repository method because it's a function. A function on itself doesn't represent any data. So this is a way you can retrieve the actual data with that function and display that.

这篇关于如何在Twig模板中使用自定义存储库方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆