Yii Framework Forum: Disable defaultScope / add exclusive scope - Yii Framework Forum

Jump to content

Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

Disable defaultScope / add exclusive scope Rate Topic: -----

#1 User is offline   yoshi 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 170
  • Joined: 28-February 09
  • Location:Germany

Posted 02 October 2009 - 11:42 AM

Hi,

well, i was searching for something to disable the defaultScope - without success.

So for my purpose a simple possibility to disable the defaultScope would be enough, but furthermore i would appreciate having something like with_exclusive_scope like RoR has which ignores all previous scopes.

I did it a quick and dirty way by adding following function to CActiveRecord
    public function withExclusiveScope()
    {
        $this->_c = new CDbCriteria();
        return $this;
    }


and calling it like
MyModel::model()->withExclusiveScope()->findbyPk($id!==null ? $id : $_GET['mid']);


But modifying core code is evil and i wanna keep my soul! ;)
Any opinions?

Regards
0

#2 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,017
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 02 October 2009 - 12:44 PM

Should be possible to implement as behavior:
http://www.yiiframew...oc/cookbook/30/
0

#3 User is offline   yoshi 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 170
  • Joined: 28-February 09
  • Location:Germany

Posted 02 October 2009 - 04:26 PM

Hi Mike,

i can't see this possibility... :blink:

Because the defaultScope is always applied to the criteria when getDbCriteria() is called for the first time where it creates the internal CDbCriteria object.

Would you explain your thoughts how to solve this in a bahavior more in detail please?!

Best Regards
0

#4 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,017
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 03 October 2009 - 07:32 AM

Oh, you're right, of course. Didn't look close enough at your code example.

Another solution might be to extend AR and use that as base class for your records. But even that would require to add some logic to defaultScope() every time.

class MyActiveRecord extends CActiveRecord
{
    private $_es=false; // flag for exclusive scope

    public function withExclusiveScope()
    {
      $this->_es=true;
      return $this;
    }

    public function getIsExclusiveScope() {
      return $this->_es;
    }
}


Then in your actual records:

class SomeRecord extends MyActiveRecord
{
    // ...

    public function defaultScope()
    {
        return $this->getIsExclusiveScope() ?
            array() :
            array( /* your default scope conditions here */ ); 
    }
}


As always: i didn't test this :)

Edit:
Oh, and this time i think this solution can be implemented as behavior, too.
0

#5 User is offline   pestaa 

  • past Yii dev member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 705
  • Joined: 07-May 09
  • Location:Hungary

Posted 03 October 2009 - 10:37 AM

Default scope is a usual approach when logical deletion is implemented, so outdated rows will never be loaded. It is also useful when you want to restrict users from accessing other people's content.

If you want to disable a scope in some cases, why would you want it to be default anyway?
0

#6 User is offline   yoshi 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 170
  • Joined: 28-February 09
  • Location:Germany

Posted 03 October 2009 - 12:29 PM

@Mike
Thank you, this is a way it could be done. But (of course) i would prefer to have this without extending AR, because i think it's nothing exceptional which is only useable for my special task...

View PostMike, on 03 October 2009 - 07:32 AM, said:

Edit:
Oh, and this time i think this solution can be implemented as behavior, too.

Ahm, but how?

View Postpestaa, on 03 October 2009 - 10:37 AM, said:

Default scope is a usual approach when logical deletion is implemented, so outdated rows will never be loaded. It is also useful when you want to restrict users from accessing other people's content.

If you want to disable a scope in some cases, why would you want it to be default anyway?


You're absolutly right, but let's take look at the case of soft deleted records: no one should see or use them, ok, so it would be more DRY to use a default scope, right?! But e.g. for administrative purpose it would be interesting to have a view where you can see all deleted records maybe with an option to undelete them. It's not acceptable to tell the admin "well, go ahead and use the sql command line to undelete a record" or something like this.
Know what i mean?!

Regards
0

#7 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,017
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 03 October 2009 - 12:47 PM

View Postyoshi, on 03 October 2009 - 12:29 PM, said:

Ahm, but how?


Actually it should be as simple as this: :)

class ExclusiveScope extends CActiveRecordBehavior
{
    private $_es=false; // flag for exclusive scope

    public function withExclusiveScope()
    {
      $this->_es=true;
      return $this->Owner;
    }

    public function getIsExclusiveScope() {
      return $this->_es;
    }
}


class SomeRecord extends MyActiveRecord
{
    // ...

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

    public function defaultScope()
    {
        return $this->getIsExclusiveScope() ?
            array() :
            array( /* your default scope conditions here */ ); 
    }
}

1

#8 User is offline   yoshi 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 170
  • Joined: 28-February 09
  • Location:Germany

Posted 03 October 2009 - 01:52 PM

@Mike
Ok, i see what you mean. But unfortunately i would still need to extend CActiveRecord :(
But anyway thanks for your prompt help and ideas - like always ;)
0

#9 User is offline   Mike 

  • Elite Member
  • PipPipPipPipPip
  • Yii
  • Group: Members
  • Posts: 3,017
  • Joined: 06-October 08
  • Location:Upper Palatinate

Posted 03 October 2009 - 02:10 PM

View Postyoshi, on 03 October 2009 - 01:52 PM, said:

Ok, i see what you mean. But unfortunately i would still need to extend CActiveRecord :(


Why that? All you should need is to add the behavior above.
0

#10 User is offline   yoshi 

  • Standard Member
  • PipPip
  • Yii
  • Group: Members
  • Posts: 170
  • Joined: 28-February 09
  • Location:Germany

Posted 03 October 2009 - 02:44 PM

View PostMike, on 03 October 2009 - 02:10 PM, said:

Why that? All you should need is to add the behavior above.

Damn it, your absolutly right! Maybe i was cross-eyed but your idea works great! :)
This is definitely a better solution than in my first post!
Thank you Mike!


But nevertheless this 'Feature Request' is still pending, because Mikes solution works very well for me but it's rather a defaultScope-switch than an exclusive scope.
0

#11 User is offline   pestaa 

  • past Yii dev member
  • PipPipPipPip
  • Yii
  • Group: Members
  • Posts: 705
  • Joined: 07-May 09
  • Location:Hungary

Posted 07 October 2009 - 10:11 AM

Sure, your feature request is valid, we'll work on it after higher priority tasks, hope you understand.

View Postyoshi, on 03 October 2009 - 12:29 PM, said:

It's not acceptable to tell the admin "well, go ahead and use the sql command line to undelete a record" or something like this.

For administration it might be even better to use database access objects.
0

Share this topic:


Page 1 of 1
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users