Reputation: 3309
Lets say, I have a class Movie with a Orm\OneToMany relation ship to the class Actors.
I have already a working example of an getter for $movie->getActors(); which will return all actors of that movie.
But how to dynamically modify the query for that? For example, I show a list of all actors of the movie, and allow the user to sort by name, age, gender, whatever.
===== EDIT ======
After learning, that such things belongs to the repository class (thanks to Yoshi, scoolnico), here is the adapted question:
Lets say, I have got a Movie ID 4711. I will fetch the movie:
$movie = $this->getDoctrine()
->getRepository("Movie")
->find(4711);
And now, I need to get all Actors from this movie sorted by name (as an example).
$actorsOfMovie = $this->getDoctrine()
->getRepository("Actor")
->findBy(array("movie_id" => 4711), array('name'=>'asc'));
Is this really the correct way? With this version, I need to know in the controller, how the relationship between movie and actors work! Thats a thing, doctrine should handle for me!
And how to use it with multiple movies?
// Controller
$movies = $this->getDoctrine()
->getRepository("Movie")
->findfindBy(array());
return $this->render("xyz.html.twig", array("movies": $movies));
// Twig: xyz.html.twig
{% for movie in movies %}
<h1>{% movie.getName() %}</h1>
<p>Actors: {% for actor in movie.getActorsOrderByName() %}{{ actor.getName() }},{% endfor %}
{% endfor %}
Upvotes: 0
Views: 1233
Reputation: 3309
I think the best solution for this is to use doctrine's Criteria class (http://docs.doctrine-project.org/en/latest/reference/working-with-associations.html#filtering-collections).
Have a look at https://www.boxuk.com/insight/blog-posts/filtering-associations-with-doctrine-2
Based on this, I can do the following:
// In the Movie Class
/**
* Get actors
*
* @param array $options
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getActors($options = array())
{
if(!$options) {
return $this->actors;
}
$criteria = Criteria::create();
if(isset($options["order_by"])) {
$criteria->orderBy($options["order_by"]);
}
if(isset($options["limit"])) {
$criteria->setMaxResults($options["limit"]);
}
if(isset($options["offset"])) {
$criteria->setFirstResult($options["offset"]);
}
// Or I can define other filters or sorting stuff
if(..) {
...
}
return $this->actors->matching($criteria);
}
Upvotes: 0
Reputation: 3135
You just have to create a specific function in your class Repository:
class MovieRepository extends EntityRepository
{
public function getActoryByGender($gender)
{
/.../
}
}
And in your controller:
/.../
$em = $this->getDoctrine()>getManager();
$repository = $em->getRepository('YourBundle:Movie');
$actors = $repository->getActorByGender('male');
/.../
Upvotes: 1