Create subclasses of Doctrine_Query for each model class
To make your model code better readable and reusable, it helps to create custom Query classes which extend Doctrine_Query. For example, when you have defined a NewsItem in your schema, upon running ./symfony doctrine:build-model a NewsItem.class.php and NewsitemTable.class.php will be generated for you. Now, also create a query class for creating NewsItem queries:
class NewsItemQuery extends Doctrine_Query
{
}
Then modify your NewsItemTable class so it looks like this:
class NewsItemTable extends Doctrine_Table
{
public function construct()
{
$this->setAttribute(Doctrine::ATTR_QUERY_CLASS, 'NewsItemQuery');
}
}
Notice the fact that it says “construct()”, not “__construct()”. It is better not to override the parent __construct() method, but to use this pseudo-construct method, which the parent class calls at the end of the real __construct() method.
The code above means: whenever a new query is created by calling Doctrine_Core::getTable('NewsItem')->createQuery() the NewsItemQuery class should be used, instead of the default Doctrine_Query class.
Now, enhance the NewsItemQuery class, for example in the following way:
class NewsItemQuery extends Doctrine_Query
{
/**
* Join the translation
*
* @param string $culture The culture for which to join the translation
* @return NewsItemQuery
*/
public function joinTranslation($culture = null)
{
if (null === $culture)
{
$culture = sfDoctrineRecord::getDefaultCulture();
}
return $this->leftJoin($this->getRootAlias().'.Translation t WITH t.lang = ?', $culture);
}
}
Now you can fetch all news items and join their translation by executing this command:
$news_items = Doctrine_Core::getTable('NewsItem')
->createQuery('n')->joinTranslation('nl')->execute();
By using a special Query class for each of your models, your code gets more readable, but will also contain less duplicate code, because you don’t have to copy the ->leftJoin(...) line all over your table class anymore.