2015-02-16 11 views
10

Utilizzando Yii2 in vista ...Yii2 modello :: find() con predefinito in cui le condizioni

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

restituisce tutti i prodotti come array. Sto cercando un modo per restituire tutti i prodotti DOVE id! = 1 Voglio che solo un posto modifichi cosa restituisce "-> all()" per ogni modello. So che lo Product::find()->where('id != 1')->... è possibile, ma non voglio scrivere e mantenerlo in più di un posto.

risposta

22

1) Si può semplicemente ignorare find() metodo nel modello:

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

Usage:

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

2) Usa scope.

Creare classe query personalizzata:

namespace app\models; 

use yii\db\ActiveQuery; 

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

     return $this; 
    } 
} 

Override find() metodo nel modello:

namespace app\models; 

use yii\db\ActiveRecord; 

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

quindi è possibile utilizzare in questo modo:

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

penso utilizzando secondo metodo è più flessibile, perché rende il codice più chiaro.

Note aggiuntive:

  • Hardcoded id non è una buona pratica. Meglio sostituirlo con condizioni equivalenti.

  • Per questi esempi ho utilizzato un modo diverso di specificare la condizione. Vedere i diversi modi di specificare le condizioni nell'istruzione where in official documentation.

+0

Ho una domanda correlata [qui] (http://stackoverflow.com/q/31434768/57091). – robsch

+3

Con il primo esempio, usando un altro 'where()' altrove nel codice - ad es. 'Product :: find() -> where (['col' => $ value]) -> all();' sovrascriverà il tuo 'default' 'where()' nel modello. C'è un modo per aggirare questo, oltre all'uso della classe scope nel secondo esempio? – JamesG

+1

@JamesG Con 'where()' già definito è necessario usare 'andWhere()'/'oWhere()' per mantenere le condizioni iniziali. – arogachev

Problemi correlati