はじめに

論理削除は、データベースのレコードを実際に削除する代わりに、全ての操作からそのレコードを隠す機能です。これは、あとでデータを復活できることを意味しています。それをするもう一つの方法はデータをアーカイブすることです。

例えば、従業員の労働時間を記録するシステムがあるとします。従業員は毎日自分の時間を記録し、その結果サボっている人をクビにするためのレポートが生成できるようになります。その人が解雇された場合、それ以降その人がシステムにアクセスできないようにしたいでしょうが、何時間働いていたかを示すデータは保持しておく必要があります。

その従業員が論理削除されたら、システムに関する限りその従業員はもはや存在しないことになります。論理削除モデルは、この「削除された」データを使用してレポートを生成することができるように、アーカイブされたデータを照会する方法を提供します。

一部の人々は論理削除を使わない事を提唱しています。このモデルは論理削除を使用することを強制はしませんが、もし論理削除が適していいるとあなたが判断したならば、それを迅速に実装する手段を提供します。

基本的な使用

論理削除モデルを使用するのは大変簡単で、単に Orm\Model の代わりに Orm\Model_Soft を継承するだけです。これによりそのモデルは論理削除に対応し、 delete() と find() メソッドの通常の振る舞いが変更されます。

class Model_Employee extends \Orm\Model_Soft
{
    ...
}

このモデルは、テーブル間の関係や使用したいプロパティ部分も含めて、通常のORM モデルのように設定します。

設定

現在のところ、論理削除モデルに2つの柄設定を行うことができます。

delete_field はタイムスタンプを保持するフィールドです。データベースではこの値は MySQL か unix のタイムスタンプでなければなりません。そしてデフォルト値は NULL です。NULL タイムスタンプを持つエントリは削除されることはありません。カラム名のデフォルト値は deleted_at です。

mysql_timestamp はタイムスタンプが MySQL のものか unix タイムスタンプかを表します。デフォルト値は true (MySQL のタイムスタンプを使う) になります。

デフォルト設定のサンプルモデル:

class Model_Employee extends \Orm\Model_Soft
{
    protected static $_soft_delete = array(
        'deleted_field' => 'deleted',
        'mysql_timestamp' => true,
    );
}

削除

論理削除は、オブジェクトを選択した後の通常の delete() メソッドの呼び出しで実行されます。これはデータベースの該当エントリにその時のタイムスタンプを記録し、エントリが削除されたマークとします。そのエントリは find() による検索に表れる事はなくなります。

$employee = Model_Employee::find(1);
$employee->delete(); // この従業員はまさに論理削除されました

検索

論理削除されたエントリは find() によってリストされることはありません。それらは Model_Soft の中においては削除されていることになっているので、結果からも取り除かれます。削除されたエントリを見つけることは、 find_deleted()deleted() を用いることで可能です。これらは find() メソッドと同じパラメータで期待したように動作します。

復元

論理削除されたエントリは後で復元することができます。つまり従業員の誰かが再び戻った場合は、論理削除されたエントリを復元するだけで、新しく従業員エントリを作成すること無く、再び彼女のためにすべてがきちんと動作するようになります。

これは削除されたエントリに対して restore()undelete() を単に呼び出すだけで完了します。

$employee = Model_Employee::find_deleted(1);
// または
$employee = Model_Employee::deleted(1);

$employee->restore(); // 従業員はもう削除されていません
$employee->undelete(); // こちらも同じ意味です

リレーション

削除

delete メソッドは、 cascade_delete が true である関係を持ったモデルも論理削除します。その関係モデルが論理削除モデルでなかった場合は、 RelationNotSoft 例外が投げられます。

復元

restore メソッドも cascade_delete が true の場合は、同様に関連するエントリを復元します。