Search code examples
yiiscopesnamed-scopes

yii detecting if scope is in use


I was wondering if there's a method to detect if a scope is being used on an AR search in yii?

For example, a model might contain 2 scopes:

class MyModel extends CActiveRecord
{
    ...
    function myScope1()
    {
        $this->getDbCriteria()->mergeWith(array(
            'join'=>'etc...',
            'condition'=>'foo = bar',
        ));
        return $this;
    }

    function myScope2()
    {
        $this->getDbCriteria()->mergeWith(array(
            'join'=>'etc...',
            'condition'=>'foo2 = bar2',
        ));
        return $this;
    }
    ....
}

I'm calling the AR like so:

$results = MyModel::model()->myScope1()->myScope2()->findAll();

It's a very dynamic site and there are more than 2 scopes, some used, some not. there are a couple of scopes that shouldn't be applied if another scope is in use. To avoid hundreds of if else statements, can I do something like so:

class MyModel extends CActiveRecord
{
    ...
    function myScope1()
    {
        $this->getDbCriteria()->mergeWith(array(
            'condition'=>'foo = bar',
        ));
        return $this;
    }

    function myScope2()
    {
        if($this->appliedScopes('myScope1')==false)
        {
            // scope myScope1 isn't applied, so apply this scope:
            $this->getDbCriteria()->mergeWith(array(
                'condition'=>'foo2 = bar2',
            ));
        }
        return $this;
    }
    ....
}

Solution

  • Typical, think of a workaround almost right after posting!

    In my case, applying 'OR' between the two scopes will work, so;

    class MyModel extends CActiveRecord
    {
        ...
        function myScope1()
        {
            $this->getDbCriteria()->mergeWith(array(
                'join'=>'etc...',
                'condition'=>'foo = bar',
            ));
            return $this;
        }
    
        function myScope2($useAnd=true)
        {
            $this->getDbCriteria()->mergeWith(array(
                'join'=>'etc...',
                'condition'=>'foo2 = bar2',
            ),$useAnd);
            return $this;
        }
        ....
    }
    

    Calling like so:

    $results = MyModel::model()->myScope1()->myScope2(false)->findAll();