先日の第4回 CakePHP 勉強会で発表した内容でもあるのですが、簡単に SoftDeletable Behavior の使い方をまとめました。(少しだけ発表ないようにない追加情報もあります)

SoftDeletable Behavior はソフトデリート(論理削除)を簡単に実現してくれる大変便利なビヘイビアです。論理削除とは DB から DELETE するのではなく削除フラグを設けて DELETE する変わりに削除フラグを立てて削除したことにすることです。

一番参考になるのはやはり Bakery です。英語が苦にならない方は私の説明よりも下記エントリを見る方がいいです。
Soft Deletable Behavior (Articles) | The Bakery, Everything CakePHP

勉強会で発表した資料は下記にありますので、よろしければこちらもご覧下さい。
CakePHP 勉強会で発表してきました | Sun Limited Mt.

インストール

上記エントリから soft_deletable.php をダウンロードして、app/models/behaviors に入れます。

モデルにビヘイビアを設定する

論理削除したいモデルに SoftDeletable Behavior を使用するように設定します。

$actsAs = array('SoftDeletable');

モデルのテーブルに以下のカラムを追加します。

ALTER TABLE `tabel_name` ADD `deleted` TINYINT NOT NULL ;
ALTER TABLE `tabel_name` ADD `deleted_date` DATETIME NULL ;

deleted が削除フラグ、deleted_date に削除した日時が入ります。

これだけで論理削除が実現できます。find などでも取得されなくなります。

論理削除したレコードを取得する方法

論理削除したレコードを含めて取得したい場合は find する前に下記のコードを実行します。

$this->Model->enableSoftDeletable(false);

論理削除を一時的に無効にすることができます。

注意点

Bake などで焼いたソースは controller の delete メソッドが下記のようになっています。

function delete($id = null) {
    if (!$id) {
        $this->Session->setFlash(__('Invalid id for Post', true));
        $this->redirect(array('action'=>'index'));
    }
    if ($this->Post->del($id)) {
        $this->Session->setFlash(__('Post deleted', true));
        $this->redirect(array('action'=>'index'));
    }
}

SoftDeletable Behavior を使用すると Model::del は必ず false が返ります。これは Behavior が beforeDelete で削除フラグを立てて、モデルの del メソッドを実行させないために false を返すためです。この点だけ注意が必要です。

しかし、カラムを2つ追加して、コードを1行追加するだけで論理削除が可能になるので、大変便利なビヘイビアです。

関連する投稿