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 будет переопределен.
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, как это описано в документации.
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/
Добавить комментарий