1

valid一部のモデルでは、MySQLのブール値を使用してソフト削除が実装されています。

クラスでは、scopesメソッドは次のように定義されています。

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

これは、モデルをロードするときにスコープを呼び出して、有効な(削除されていない)モデルのみを他の検索基準と一緒に含めることができるようにするためです。

これはあまり乾燥しているわけではなく、同じことを実現する別の方法があるかどうか疑問に思っています。これは、インターフェイス、すべてのモデルが派生する抽象Modelクラス、または5.4を使用している場合は特性に適用できる可能性があります。

4

1 に答える 1

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(もちろん、このクラスにはさらに多くのメソッドがありますが、メソッドを拡張する必要がある場合は、親メソッドを呼び出す必要があるという欠点があります):

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 に答える