如何在Twig模板中使用自定义存储库方法? [英] How to use custom repository methods in Twig template?
问题描述
用户
和一个实体 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%}
一些注意事项:
- 对于多个用户,您将不得不更改查询(懒加载是可能的,但不建议)。
- 如果数据很多,可以通过获得标量结果来获得性能提升(Array)
- 如果您对不能组合的用户需要不同的查询,则必须存储不同的变量(对象或数组)。这就是为什么我把它命名为user_with_books。但是,如果您只在模板中使用此用户,您可以将其称为用户。
-
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:
- For multiple users you will have to change the query (lazy loading is possible but not advised).
- If it's a lot of data you can get a performance boost by getting a scalar result (Array)
- 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".
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屋!