===== CactiveRecord : scopes ===== Podemos asociar un nombre a un conjunto de filtros, y después aplicarlo al cargar datos (con find(), findAll(), etc, y en los dataprovider). Estos filtros con nombre son los **scopes** class Entradas extends CActiveRecord { … public function scopes() { return array( 'aceptadas'=>array( 'condition'=>'aceptada=1', ), 'recientes'=>array( 'order'=>'fecha_alta DESC', 'limit'=>5, ), ); } … } Para usarlo al cargar información:, $entradas=Entradas::model()->aceptadas()->recientes()->findAll() o $provider=new CActiveProvider(Entradas::model()->recientes()); Se pueden definir filtros con parámetros, para tener mayor flexibilidad: class Entradas extends CActiveRecord { … public function recientes($limite=5) { $this->getDbCriteria()->mergeWith(array( 'order'=>'fecha_alta DESC', 'limit'=>$limite, )); return $this; } … } //Por ejemplo, para cargar las 3 últimas entradas aceptadas $entradas=Entradas::model()->aceptadas()->recientes(3)->findAll() Se pueden utilizar también al definir relaciones: class Post extends CActiveRecord { … public function relations() { return array( … 'recentPublishedComments'=>array(self::BELONGS_TO, 'Post', 'post_id', 'scopes' => array('published', 'recent')), … ); } … } class User extends CActiveRecord { … public function relations() { return array( … 'posts'=>array(self::HAS_MANY, 'Post', 'author_id', 'with'=>'comments:approved'), … ); } … } === Default scope === Se aplica a todas las búsquedas, aunque no se especifique explicitamente: class Post extends CActiveRecord { … public function defaultScope() { return array( 'condition'=>"language='".Yii::app()->language."'", ); } … } También se pueden aplicar con with(): $posts=Post::model()->published()->with('comments')->findAll(); … $posts=Post::model()->with('comments:published:today')->findAll(); Los scopes se aplican únicamente a las sentencias SELECT de sql, pero podemos cargar su definición para aplicarlos a otras sentencias: Post::model()->deleteAll( Post::model->disabled()->getDbCriteria() ); // o también … $scopes=Post::model()->scopes(); Post::model()->deleteAll($scopes['disabled']); … Si se quiere aplicar un nuevo scope, antes hay que llamar a resetScope() … $old = Post::model()->published()->recently(); $new = Blog::model()->resetScope()->today(); Para evitar problemas de ambigüedad cuando se hacen accesos a varias tablas, se puede poner un alias a las condiciones: public function scopes() { $t=$this->getTableAlias(false); //Devuelve el alias del modelo en la SQL return array( 'published'=>array('condition'=>"$t.published=1"), ); }