2015-02-16 3 views
10

Использование Yii2 в представлении ...Yii2 модель :: найти() с дефолтом, где условия

Products::find()->asArray()->all() 

возвращает все продукты, как массив. Я ищу способ вернуть все продукты WHERE id! = 1 Я хочу иметь только одно место, чтобы изменить, что "-> all()" возвращается для каждой модели. Я знаю, что Product::find()->where('id != 1')->... возможно, но я не хочу писать и поддерживать его в нескольких местах.

ответ

22

1) Вы можете просто переопределить find() метод в вашей модели:

/** 
* @return \yii\db\ActiveQuery 
*/ 
public static function find() 
{ 
    return parent::find()->where(['<>', 'id', 1]); 
} 

Использование:

$products = Products::find()->all(); 

2) Использование scope.

Создать пользовательский класс запроса:

namespace app\models; 

use yii\db\ActiveQuery; 

class ProductQuery extends ActiveQuery 
{ 
    public function withoutFirst() 
    { 
     $this->andWhere(['<>', 'id', 1]); 

     return $this; 
    } 
} 

Override find() метод в вашей модели:

namespace app\models; 

use yii\db\ActiveRecord; 

class Product extends ActiveRecord 
{ 
    /** 
    * @inheritdoc 
    * @return ProductQuery 
    */ 
    public static function find() 
    { 
     return new ProductQuery(get_called_class()); 
    } 
} 

Затем вы можете использовать его как это:

$products = Products::find()->withoutFirst()->all(); 

Я думаю, используя второй метод является более гибким, поскольку он делает код более понятным.

Дополнительные примечания:

  • Запрограммированные id не является хорошей практикой. Лучше замените его эквивалентным условием.

  • Для этих примеров я использовал другой способ задания условия. См. Различные способы задания условия в операторе where в official documentation.

+0

У меня есть связанный с этим вопрос [здесь] (http://stackoverflow.com/q/31434768/57091). – robsch

+3

В первом примере, используя другой 'where()' в другом месте вашего кода - например, 'Product :: find() -> где (['col' => $ value]) -> all();' будет перезаписывать ваш 'default' 'where()' в модели. Есть ли способ обойти это, кроме использования класса scope во втором примере? – JamesG

+1

@JamesG С '' где() 'уже определено, вам нужно использовать' andWhere() '/' илиWhere() ', чтобы сохранить начальное условие. – arogachev

Смежные вопросы