CSS NITE in KANSAI, LP1 プレセッション第二弾に間に合わなかった。
悔しいからいっそブログでも更新する。

今回は…behavior。
modelにbehaviorsメソッド作って配列で返したらいい。

	public function behaviors()
	{
		return array(
			'application.components.shimi.shimiSoftDelete'
		);
	}

そしてshimiSoftDelete.phpを用意してshimiSoftDeleteクラスを作る。

class shimiSoftDelete extends CActiveRecordBehavior
{
	private $delete_colum		= 'status';	//int型のフィールド
	private $delete_date_colum	= 'update_time';	//tiemstampかdatetimeか何か。

	public function beforeDelete( $event )
	{
		$this->getOwner()->{$this->delete_colum}	= 0;
		$this->getOwner()->{$this->delete_colum}	= new CDbExpression('NOW()');

		//保存する感じで。
		$this->getOwner()->update();

		//falseを返して物理削除を実行させない。
		//強制モードとかつけるならココでtrue返せば普通に削除してくれる。
		//ただしtrueを返さないとatferDeleteが動かないので注意。

		$event->isValid = false;
	}
	public function beforeFind( $event )
	{
		$this->getOwner()->getDbCriteria()->mergeWith( array('condition'=>$this->delete_colum.'=1') );
	}
}

まぁ、見てわかるようにbeforeDeleteとかbeforeFindの前処理を追加します。
その他にもafterDeleteとか各アクションの前後にあるんで好きなの使えばいいよ。

感想。
基本的にソフトデリート(倫理削除)じゃないと仕事で使えないじゃないですか?
で、今回はcrudで作ったmodelのdeleteアクションをソフトデリートにするbehaviorを用意してみたワケです。
もちろん、イチイチclass作らないでmodelにbeforeFindメソッドとか書いてもいいよ。

ちなみに、イチイチbeforeFindより簡単(?)にしたければScope使うのがいいと思うよ。
Scopeについては詳しくは公式みればOKです。

そんな感じで。
明日のCSS NITE in KANSAI, LP1はちゃんと間に合おうと誓った次第であります。

追記:忘れた頃に。
現在のYii PHP framework 1.1.1ではbeforeFind()が正常に動かないのでアレです。
あと、dataprovidorのpagerで利用される総数を取得するcount()でも適用されないです。
これは1.1.0でも同様です。
※だから総数が削除済みも含めた数になっちゃう。

そんな感じなのでsoftDeleteを実装する際には
[1] Yii 1.1.0を使うか、1.1.1のquery()を修正(applyScopesとbeforeFind順番を変える)する。
[2] dataprovidorを使う際にはcount()も修正する(applyScopesの前にbeforeFind()追加)。

defaultScope使えてのはナシな(・∀・)なんとなく!

関連する記事

  1. Widget試してみる Yii Framework触るぜ日記(12)
  2. あれ? Yii Framework触るぜ日記(7.5)