Как правильно задать в Yii2 default scope

от автора

Yii2 зарелизился не так давно, и пока, документация не полная, а рецепты в интернете не всегда верные.

Проблема default scope в Yii2 существует уже больше года, еще с того времени, как Yii2 был в бета версии. Соответственно при поиске нас кидает на различные обсуждения, среди которых преобладает кривое решение, препятствующее нормальному наследованию классов.
Я хочу поделиться своим вариантом, который решает проблемы наследования.

Не верное решение Default scope, которое преобладает при поиске, выглядит так:

Не используйте этот код:

class ActiveRecord extends \yii\db\ActiveRecord {     public static function find()     {         return parent::find()->andWhere(['active' => 1]);     } } 

Если мы заходим добавить обычный scope, так как написано в документации (путем наследования от ActiveQuery), метод find будет переопределен.

Пример добавления scope из документации:

namespace app\models;  use yii\db\ActiveRecord; use yii\db\ActiveQuery;  class Comment extends ActiveRecord {     public static function find()     {         return new CommentQuery(get_called_class());     } }  class CommentQuery extends ActiveQuery {     public function active($state = true)     {         return $this->andWhere(['active' => $state]);     } } 

Верное решение для default scope

Правильная реализация Default scope — создать свой класс наследованный от ActiveQuery, и возвращать его в методе find. Так-же в этом ActiveQuery можно прописывать другие scopes, как это описано в документации.

Верная реализация Default scope:

class MyActiveRecord extends \yii\db\ActiveRecord {     public static function find()     {         return new MyActiveQuery(get_called_class());     } } 

class MyActiveQuery extends \yii\db\ActiveQuery {     public function init()     {         $modelClass = $this->modelClass;         $tableName = $modelClass::tableName();         $this->andWhere([$tableName.'.active' => 1]);         parent::init();     }  }  

Таким образом, в наследуемых MyActiveRecord моделях, мы будем иметь доступ ко всем scopes, а если захотим добавить еще default scope или обычные scopes, можно аналогично расширять MyActiveQuery.

ссылка на оригинал статьи http://habrahabr.ru/post/255545/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *