Reputation: 21184
I'm building a small website with Symfony2 and Doctrine2. There are blog posts, events and press releases. Each of these is so similar that I decided to use single table inheritance (STI) with a parent table called 'Node'.
Nodes have:
By default, I only want to display published nodes that are from the current locale.
Obviously, I could create lots of queries in the repository that look something like:
$this->createQueryBuilder('Event')
->where('Node.published = 1')
->where('Node.locale = :locale')
but this doesn't seem very DRY.
So how do I build a default query which other queries can 'inherit' from? This should include default Doctrine queries based on relations.
Upvotes: 1
Views: 1646
Reputation: 62894
Inheritance is probably overkill.
Why not just create a little factory method that gives you a preconfigured queryBuilder?
class NodeRepository extends Doctrine\ORM\EntityRepository {
public function getLocalizedNodeQueryBuilder($type,$locale){
return $this->getQueryBuilder($type)
->where('Node.published = 1')
->where('Node.locale = :locale')
->setParameter('locale',$locale);
}
}
You could do the same thing, and simply override getQueryBuilder if you're sure you always want your querybuilder configured that way.
Upvotes: 4
Reputation: 4756
You don't need to build anything like that into your repository classes. If you set up single table inheritance with a "Discriminator Map" you'll end up with seperate classes (Entities). Doctrine will take care of filtering by your "node type" when it interacts with the DBAL.
For example..
namespace MyProject\Model;
/**
* @Entity
* @InheritanceType("SINGLE_TABLE")
* @DiscriminatorColumn(name="discr", type="string")
* @DiscriminatorMap({"node" = "Node", "blogpost" = "Blogpost", "events" = "Events"})
*/
class Node
{
// ...
}
/**
* @Entity
*/
class Blogpost extends Node
{
// ...
}
/**
* @Entity
*/
class Events extends Node
{
// ...
}
// get me all the blogposts
$blogposts = $em->getRepository('Blogpost')->findAll();
// get me all the events
$events = $em->getRepository('Events')->findAll();
This is especially beneficially as you'll be able to encapsulate your "Blogpost" logic into its own entity, rather than trying to represent it with its parent class "Node".
Upvotes: 2