1

对于某些模型,我们valid在 MySQL 中使用布尔值实现了软删除。

在类中,scopes方法定义如下:

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

这样当我们加载模型时,我们可以调用作用域,使其仅包含有效(未删除)模型以及其他查找条件,或者任何它发生的情况。

这不是很干,我想知道是否有另一种实现相同目标的方法,它可能适用于接口,所有模型派生自的抽象模型类,或者,如果使用 5.4,一个特征。

4

1 回答 1

3

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

软删除行为.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(我当然在这个类中有更多的方法,缺点是如果你需要扩展方法,你需要调用父方法):

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

PROTIP : 当你使用 gii 生成模型时,你可以指定你自己的 ActiveRecord 类

于 2012-08-23T17:03:36.637 回答