Herramientas de usuario

Herramientas del sitio


cursos:yii:clases:activerecord:scopes

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(); </code>

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"),
    );
}