- Published on
doctrine教程12---过滤关系集合
- Authors
-
-
- Name
- langziyang
-
doctrine教程12---过滤关系集合
我们修改一下模板:
{% extends 'base.html.twig' %}
{% block body %}
<h1 class="text-3xl p-5 text-center my-4 font-semibold"><span class="fa {{ category.iconKey }}"></span> {{ categoryName }} Fortunes</h1>
<div class="flex justify-center mb-16 px-4">
<div>
<table class="table-auto border mb-6">
<thead class="bg-slate-500 text-white">
<tr>
<th class="border p-4">
Fortunes
</th>
<th class="border p-4">
Print History ({{ fortunesPrinted|number_format }} total, {{ fortunesAverage|number_format }} average)
</th>
</tr>
</thead>
<tbody>
{% for fortuneCookie in category.fortuneCookies %}
<tr class="hover:bg-slate-200">
<td class="border p-4">
{{ fortuneCookie.fortune }}
</td>
<td class="border p-4">
{{ fortuneCookie.numberPrinted }} printed since {{ fortuneCookie.createdAt|date('M jS Y') }}
</td>
</tr>
{% endfor %}
</tbody>
</table>
<a class="text-slate-700 hover:text-slate-900 font-semibold" href="{{ path('app_homepage') }}"><i class="fa fa-angle-double-left"></i> Back to Fortune Categories</a>
</div>
</div>
{% endblock %}
但是我们的FortuneCookie有一个$discontinued属性,我们只需要取值为false的数据,我们可以单独创建一个查询,但这太费事了,我们先去控制器把 findWithFortunesJoin修改为find(),这只是为了更容易看到我们接下来要做的事情
打开Category.php找到getFortuneCookies()方法,在下面添加一个getFortuneCookiesStillInProduction()的新方法,接下来我们可以在方法里 循环$this->fortuneCookies as $fortuneCookie,这是最简单的,但是如果我们想取其中10个结果,首先得取出所有数据,可能成百上千个,太浪费了。
我们真正想做的是选择Doctrine查询时添加一个WHERE discontinued = false,很简单,我们在方法添加下面的代码
public function getFortuneCookiesStillInProduction(): Collection
{
$criteria = Criteria::create()
->andWhere(Criteria::expr()->eq('discontinued', false));
return $this->fortuneCookies->matching($criteria);
}
然后我们去twig上修改
{% for fortuneCookie in category.fortuneCookiesStillInProduction %}
<tr class="hover:bg-slate-200">
<td class="border p-4">
{{ fortuneCookie.fortune }}
</td>
<td class="border p-4">
{{ fortuneCookie.numberPrinted }} printed since {{ fortuneCookie.createdAt|date('M jS Y') }}
</td>
</tr>
{% endfor %}
代码是不是正常工作了?是不是特别简单?缺点是查询的逻辑放在了实体文件而不是储库中,但我们其实可以移过去
打开FortuneCookieRepository.php,添加一个方法createFortuneCookiesStillInProductionCriteria()返回Criteria对象
注意这是一个静态方法,因为我们在Category.php里访问存储库对象,回到Category.php修改代码
public function getFortuneCookiesStillInProduction(): Collection
{
$criteria = FortuneCookieRepository::createFortuneCookiesStillInProductionCriteria();
return $this->fortuneCookies->matching($criteria);
}
在首页我们也有同样的需求,统计的都是所有数据,把({{ category.fortuneCookies|length }})修改为({{ category.fortuneCookiesStillInProduction|length }})
完全工作了,但这并不是最好的部分,如果我们希望在网站上的任何地方都这样过滤呢?