Doctrineの論理削除
Doctrineでfind使いたいんだけど論理削除があるからどうしてもできない!
ってことでgoogle:doctrine 論理削除でググッてみた。
アシアルブログですごくいいエントリーが沢山ヒット。
ただ少し古いのでアシアルブログのエントリを参考にDoctrineの公式サイトを直接見に行ったりして
Doctrine 1.2.4、Symfony1.4.10で動作するところまで調査できた。
DoctrineはデフォルトでSoftDeleteというモデルビヘイビアというものを持っている。
以下参照
- http://www.doctrine-project.org/documentation/manual/1_0/ja/behaviors
- http://www.doctrine-project.org/documentation/manual/1_0/ja/behaviors:%E3%82%B3%E3%82%A2%E3%83%93%E3%83%98%E3%82%A4%E3%83%93%E3%82%A2:softdelete
ただし、ここで使用されるカラムのデフォルトの名称はdeleted_atである。
今回のプロジェクトで設計したテーブルは論理削除はすべてdel_flagという
名称であるため変更する必要がある。
変更対象となるクラスはDoctrine_Template_SoftDelete
これを継承してDelFlagという名称に変更する。
Doctrineのtemplateの置き場に迷ったがlib/model/doctrine/template
と新しく作成してその中に格納することにした。
mkdir %SF_LIB_DIR%/lib/model/doctrine/template touch %SF_LIB_DIR%/lib/model/doctrine/template/DelFlag.class.php
プロパティのみの変更で動作するため$_optionsのnameのみ変えれば良い。
<?php // lib/model/doctrine/template/DelFlag.class.php class DelFlag extends Doctrine_Template_SoftDelete { /** * Array of SoftDelete options * * @var string */ protected $_options = array( 'name' => 'del_flag', 'type' => 'boolean', 'length' => null, 'options' => array( 'notnull' => false ), 'hardDelete' => false ); } ?>
一応新規で作成したディレクトリをautoload.ymlに登録する。
# apps/%YOUR_APP_NAME%/config/autoload.yml model_template: name: model template path: %SF_LIB_DIR%/model/template recursive: false
実際に利用するためにはschema.ymlに記載してbuildする必要がある。
ここでは仮にAccountというモデルに対して論理削除を設定するということにする。
# config/doctrine/schema.yml Account: columns: actAs: DelFlag: {}
以下のコマンドでモデルが生成される。
./symfony cc ./symfony doctrine:build --all --auto-load
<?php // lib/model/doctrine/base/BaseAccount.class.php public function setUp() { $delflag0 = new DelFlag(array( )); $this->actAs($delflag0); }
ProjectConfigurationにDoctrine用の記述をして完成。
<?php // config/ProjectConfiguration.class.php public function configureDoctrine($manager) { $manager->setAttribute(Doctrine::ATTR_USE_DQL_CALLBACKS, true); }
あとは動作チェック。
$account->delete();などと発行すると実際に行は残っており
論理削除のフラグ(del_flag)が1になったことを確認できる。
以上ちょっと便利だったのでブログにおこしました。