Disable default scope in relation

In my Company model i have set a default scope like this (and a exclusive scope class (behavior) to disable it:


public function behaviors()

    {

        return array(

            'ExclusiveScope' => array('class'=>'ExclusiveScope')

        );

    }


    /**

    * Only view active companies

    **/

    public function defaultScope()

    {

        return $this->getIsExclusiveScope() ?

            array() :

            array(

                'condition' => 'isActive = 1'

            );

    }

But now i have a problem. I have a dataprovider for Phone with a relation (user) in it (with a nested relation (user.company)). User is a relation of Phone and Company is a relation of User. In my Phone model i have this:


// Criteria

$criteria=new CDbCriteria;

$criteria->with = array('user', 'user.company');

But i want to disable the default scope for company for this, so that is takes all companies, instead of the active (isActive) ones. How can i achieve this?

Hi!

I met similar problem:

I have Locations model, and have item relation.

And I need to get all items belonging to that location( get location->item).

To archive it, I do not use item property, defined in relations.

Instead, I use AfterFind method for location, and search all items for the location in afterfind.

I know, it is not best, but it works.

Hi.

You can use resetScope()

How this can be applied to relations?

For example i have model Comment with relation Ticket.

Ticket has default scope.

When I use Comment, how i can reset scope for Ticket?

$comment->ticket.

Sorry, I haven’t noticed you’re talking about relations.

AFAR, the simplest way is to create another relation, e.g. if you have something like this:


public function relations()

{

    return array(

        'ticket' => array(self::BELONGS_TO, '', 'ticket_id'),

    );

}

you can change it to something like this:


public function relations()

{

    return array(

        'ticket' => array(self::BELONGS_TO, '', 'ticket_id'),

        'visibleTicket' => array(self::BELONGS_TO, '', 'ticket_id', 'scopes' => array( 'resetScope' )),

    );

}

and then use “with(array(‘visibleTicket’))” and “$comment->visibleTicket”.

Sorry, I haven’t tested this code, but I think you got the main idea.

Take a look at ‘scopes’ attribute in RAR docs.

I use getTableAlias for solve this problem


public function defultScope() {

    $t = $this->getTableAlias(false, false);

    return $t == 't' ? array(

        'order'=>"$t.name",

    ) : array();

}

Another solution is to create a subclass ExclusiveCompany that has an empty defaultScope, like this:




class ExclusiveCompany extends Company {


   public function defaultScope()

   {

       return array();

   }


}



Then create an extra relation in the User class:




public function relations()

{

    return array(

        'company' => array(self::BELONGS_TO, 'Company', 'company_id'),

        'exclusiveCompany' => array(self::BELONGS_TO, 'ExclusiveCompany', 'company_id'),

    );

}



Then you can use:




// Criteria

$criteria=new CDbCriteria;

$criteria->with = array('user', 'user.exclusiveCompany');



One of the nicest things doing like this is that, from this point on, you can have another MVC-set with this new ExclusiveCompany model. You can, for example, set specific AccessControl rules (e.g. a super user role), separating access to the (active) Company objects from the ExclusiveCompany objects (being all Company objects both active and non-active).