Skip to content

Create subclasses of Doctrine_Query for each model class

by Matthias Noback on August 19th, 2011

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.

No comments yet

Leave a Reply

Note: XHTML is allowed. Your email address will never be published.

Subscribe to this comment feed via RSS