I have two entities. Tasks and Department.
One department can have many tasks.
/**
* @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;
}
}
I also have a view that shows all departments and their related tasks.
{% for department in departments %}
{% for task in department.tasks %}
...
{% endfor %}
{% endfor %}
This then gives me a few columns each filled with tasks.
I would now like to change this so that each column only shows the most imminent tasks (due within the week) ordered by due date.
To this end I have created the TaskRepository
class with a custom query:
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();
}
}
Now, if this was a page with just one department I would simply call the custom query in my controller, and pull that into the view.
However the fact that I am showing all departments with all their imminent tasks makes that a bit untidy in the controller, as it would force me to build up an array of departments and their tasks.
This feels ugly considering that currently I just needed to loop over department.tasks
in twig and it knows to pull tasks related to the department entity.
I also know that I shouldn't (and can't easily) call the custom query in the repository in my department entity.
So what I am trying to find out is - can I somehow bind a bespoke query like described to the related entity so that doctrine knows that when I ask for tasks on a department it must go and not get all but the defined subset?
Ideally I'd like to be able to bypass end up with a twig template like below by calling on something like tasksDueSoon
without having to add loads of extra logic to the controller (or elsewhere for that matter.
{% for department in departments %}
{% for task in department.tasksDueSoon %}
...
{% endfor %}
{% endfor %}
If that's not possible and I have to go down the route of a custom array via the controller that's fine of course but it feels wrong so was hoping there's a nicer way to do this in Syomfony and tell the Department entity to use the task repository or something.
I always hesitate to post an answer without testing the actual code but here goes. The trick is to load the recent tasks at the same time you load the departments.