2012-08-23 48 views
1

对于某些模型,我们使用MySQL中的valid布尔值实现了软删除。Yii中的范围 - 在新模型上实施模式

在课堂上,作用域方法的定义如下:

public function scopes() { 
    return array(
     'valid'=>array(
      'condition'=>"t.valid=1", 
     ) 
    ); 
} 

这是这样,当我们加载一个模型中,我们可以调用的适用范围,使其包括唯一有效的(未删除)模型旁边的其他查找标准,或者它发生的任何事情。

这不是非常干燥,我想知道是否有其他方法来实现相同的事情,也许可以应用到接口,所有模型派生的抽象模型类,或者,如果使用5.4 ,一个特点。

+0

你不能简单地做T- $>有效,其中有效的(而不是范围)的属性?你可以测试if($ t-> valid)。当然,核心问题是MySQl不支持布尔值,所以你实际上正在测试一个整数。有人可能会认为,如果可能不是非常干的话,您的原始解决方案会更好(适用于所有数据库)。 –

回答

3

Yii有一个名为Behaviors 的功能,它类似于php 5.4特性,但也适用于早期版本。

SoftDeleteBehavior.php:

class SoftDeleteBehavior extends CActiveRecordBehavior { 
    public $deleteAttribute = 'valid'; 
    public $deletedValue = 0; 

    public function beforeDelete($event) { 
     if ($this->deleteAttribute !== null) { 
      $this->getOwner()->{$this->deleteAttribute} = $this->deletedValue; 
      $this->getOwner()->update(array($this->deleteAttribute)); 

      // prevent real deletion of record from database 
      $event->isValid = false; 
     } 
    } 

    /** 
    * Default scope to be applied to active record's default scope. 
    * ActiveRecord must call this from our own default scope. 
    * @return array the scope to be applied to default scope 
    */ 
    public function defaultScope() { 
     return array(
      'condition' => $this->getOwner()->getTableAlias(false,false).'.'.$this->deleteAttribute 
       . ' <> '.var_export($this->deletedValue, true), 
     ); 
    } 
} 

然后,我有这个类从行为适用deafultscope: ActiveRecord.php(我ofcourse在这个班,更多的方法,缺点是你需要调用当父方法你需要扩展方法):

class ActiveRecord extends CActiveRecord { 

    public function defaultScope() { 
     $scope = new CDbCriteria(); 

     foreach ($this->behaviors() as $name => $value) { 
      $behavior = $this->asa($name); 
      if ($behavior->enabled && method_exists($behavior,'defaultScope')) { 
       $scope->mergeWith($behavior->defaultScope()); 
      } 
     } 



     return $scope; 
    } 
} 

然后你在你的模型使用它:

class MyModel extends ActiveRecord { 
    public function behaviors() { 
     return array(
      'SoftDeleteBehavior' => array(
       'class' => 'application.components.behaviors.SoftDeleteBehavior', 
      ), 
     ); 
    } 
} 

普罗蒂普:当你产生与GII的模型,你可以指定自己的ActiveRecord类