【发布时间】:2017-09-07 12:11:57
【问题描述】:
我有两个实体。任务和部门。
一个部门可以有很多任务。
/**
* @ORM\Entity
* @ORM\Table(name="departments")
*/
class Department
{
/**
* @ORM\OneToMany(targetEntity="Task", mappedBy="department")
*/
public $tasks;
/**
* @return ArrayCollection|Task[]
*/
public function getTasks()
{
return $this->tasks;
}
}
.
/**
* @ORM\Entity
* @ORM\Table(name="tasks")
*/
class Task
{
/**
* @ORM\ManyToOne(targetEntity="Department", inversedBy="tasks")
*/
public $department;
/**
* @return Department
*/
public function getDepartment()
{
return $this->department;
}
}
我还有一个显示所有部门及其相关任务的视图。
{% for department in departments %}
{% for task in department.tasks %}
...
{% endfor %}
{% endfor %}
这给了我几列,每列都填满了任务。
我现在想更改此设置,以便每列仅显示按截止日期排序的最紧迫的任务(一周内到期)。
为此,我创建了带有自定义查询的TaskRepository 类:
class TaskRepository extends EntityRepository
{
/**
* @param Department $department
* @return Task[]
*/
public function findAllRecentTasksForGenus(Department $department)
{
return $this->createQueryBuilder('task')
->andWhere('task.department = :department')
->setParameter('department', $department)
->andWhere('task.dueDate> :dueDate')
->setParameter('dueDate', new \DateTime('-1 week'))
->orderBy('task.dueDate', 'DESC')
->getQuery()
->execute();
}
}
现在,如果这是一个只有一个部门的页面,我只需在我的控制器中调用自定义查询,并将其拉入视图。
然而,我向所有部门展示所有迫在眉睫的任务这一事实使得控制器中的内容有点凌乱,因为这将迫使我建立一系列部门及其任务。
考虑到目前我只需要在 twig 中循环 department.tasks 并且它知道拉取与部门实体相关的任务,这感觉很难看。
我也知道我不应该(也不能轻易地)在我的部门实体的存储库中调用自定义查询。
所以我想知道的是 - 我是否可以以某种方式将描述的定制查询绑定到相关实体,以便学说知道当我要求一个部门的任务时,它必须去并且除了定义的子集之外没有得到所有?
理想情况下,我希望能够通过调用 tasksDueSoon 之类的东西来绕过像下面这样的树枝模板,而无需向控制器(或其他地方)添加大量额外的逻辑。
{% for department in departments %}
{% for task in department.tasksDueSoon %}
...
{% endfor %}
{% endfor %}
如果这是不可能的,我必须通过控制器沿着自定义数组的路线走,这当然很好,但感觉不对,所以希望在 Symfony 中有更好的方法来做到这一点,并告诉部门实体使用任务库什么的。
【问题讨论】:
-
将您的查询移动到部门存储库并将其命名为 findDepartmentsWithRecentTasks。在 select 子句中,添加“任务”。因此,现在当您查询您的部门时,它们将仅包括最近的任务。无需更改树枝模板。
-
@Cerad - 这基本上就是我想要的,但我不能安静地让它工作。您介意用示例代码添加答案吗?
标签: php symfony doctrine twig symfony-3.3