How to add a named scope to ActiveRecords with a behavior

You are viewing revision #1 of this wiki article.
This version may not be up to date with the latest version.
You may want to view the differences to the latest version.

next (#2) »

Since Yii 1.0.5 you can use named scopes with ActiveRecords. They are a great help in simplifying your query calls.

For example, say we have a lot of tables with a CreatedAt column containing an integer UNIX timestamp. Now we want to add a named scope called between($start,$end) to all our ActiveRecords so that in the end we could simply use it like this:

$start=strtotime('2009-01-01');
$end=strtotime('2009-12-31');
Post::model()->between($start,$end)->findAll($someCriteria);

This should return all Posts, matching $someCriteria but only those created between $start and $end.

So let's first start with the named scope. Named scopes are usually defined in a method called scope in our ActiveRecord. Since our named scope has parameters, we need to add an explicit method instead:

public function between($start,$end)
{
    $this->getDbCriteria()->mergeWith(array(
        'condition'=>'CreatedAt BETWEEN :start AND :end',
        'params'=>array(':start'=>$start, ':end'=>$end)
    ));
    return $this;
}

We could add this method to an ActiveRecord and between would be ready to use. But as we want to have this feature for all our models, we will create a behavior instead. Therefore we put the code inside a class and modify it a little:

class BetweenBehavior extends CActiveRecordBehavior
{
    public function between($start,$end)
    {
        $this->Owner->getDbCriteria()->mergeWith(array(
            'condition'=>'CreatedAt BETWEEN :start AND :end',
            'params'=>array(':start'=>$start, ':end'=>$end)
        ));
        return $this->Owner;
    }
}

We should save this file as BetweenBehavior.php and put it somewhere where our application can find it (e.g. into an imported directory). Finally we have to add our behavior to all model files. To do that, we add a method called behaviors:

class Post extends CActiveRecord {

    // ...

    public function behaviors()
    {
        return array(
            'BetweenBehavior' => array('class'=>'BetweenBehavior')
        );
    }

    // ...
}

That's it. Our named scope is ready to use with Post. Feel free to improve the above code or come up with your own ideas for named scopes that are good candidates for a behavior.

2 0
10 followers
Viewed: 35 873 times
Version: Unknown (update)
Category: Tutorials
Tags:
Written by: Mike
Last updated by: yiqing95
Created on: Apr 30, 2009
Last updated: 12 years ago
Update Article

Revisions

View all history