SoftDelete
SoftDelete:日本語版
レコードを削除する際に、本当に削除(物理削除)するのではなく
削除フラグを立てることによって、削除モードにする(論理削除)機能。
OpenPNE:3.8.15
Symfony:1.4.13
doctrine:1.2.4
ここまで実装方法などについて書いてきましたが、実はこれだけだと動きません。
Doctrineのデフォルトの設定では、Doctrine_Queryを実行前後で修正することが出来なくなっており、そこを設定してあげる必要があります。この設定の方法がsymfony 1.0とsymfony 1.1で変わってきます。symfony 1.1ではProjectConfigurationクラスに設定を記述します。
アシアルブログ:Doctrineで論理削除を意識せずに扱う
- class ProjectConfiguration extends sfProjectConfiguration
- {
- protected $plugins = array('sfDoctrinePlugin');
- public function configureDoctrine($manager)
- {
- $manager->setAttribute(Doctrine::ATTR_USE_DQL_CALLBACKS, true);
- }
- }
OpenPNE3 では、こういう設定を追加する場所が用意されているっぽい。
まだ、成功体験をしていないので、本当にこれでよいかは不明。
- public function setupProjectOpenPNEDoctrine($manager)
- {
- // You can write your own configurations.
- // In default, OpenPNE uses foreign key.
- // If you want not to use foreign key, comment out the following configuration:
- // $manager->setAttribute(Doctrine::ATTR_EXPORT, Doctrine::EXPORT_ALL ^ Doctrine::EXPORT_CONSTRAINTS);
- $manager->setAttribute(Doctrine::ATTR_USE_DQL_CALLBACKS, true);
- }
- Category:
- actAs:
- - SoftDelete
カラム名やデータ型を変更したい場合は、下記のように記述すればよいみたい。
Symfony world:Doctrine SoftDelete behavior usage
→この記事のコメント投稿内情報。未検証。
- Category:
- actAs:
- SoftDelete:
- name: is_deleted
- type: datetime
力技でやっている人もいるみたい。
@chisei のはてなブログ:Doctrineの論理削除
このように設定することで、当該テーブルへ deleted_at カラムが追加される
んだけど・・・
公式マニュアル では、delete カラムが追加される、とされている。
データ型も、公式マニュアルでは、TYNYINT とあるけど、実際は DATETIME になる。
バージョンの問題かしらね~。
んで、実際に試してみた。
CSV で、データを突っ込む際に、deleted_at カラムには null を指定しておいたところ
当該カラムの値は 0000-00-00 00:00:00 となった。
文系プログラマによるTIPSブログ:MySQLのload dataで日付型にnullをセットする
こちらの記事がビンゴ!
- LOAD DATA
- LOCAL INFILE 'data.csv'
- INTO TABLE [table_name]
- FIELDS TERMINATED BY ','
- ENCLOSED BY '"'
- SET
- deleted_at = nullif(deleted_at, '0000-00-00 00:00:00')
- ;
上記記事では、指定項目がもっといっぱいあったけど
ひとまず、私の今回の環境およびデータでは、上記 SQL にて、
無事に daleted_at カラムへ Null 値を放り込めた。
どうやら第2引数に、データ型に合わせたデフォルト値を設定するみたい。
なので、その他のデータ型は下記の通り。
- SET
- datetime = nullif(datetime, '0000-00-00 00:00:00')
- date = nullif(date, '0000-00-00')
- time = nullif(time, '00:00:00')
- $result = $this->createQuery('c')
- ->execute();
データ取得を試みたところ
取得データ数は 0 。
SQL の確認 のごとく、発行された SQL 文を確認すると、
ちゃんと WHERE 句が付記されている。
- WHERE (o.deleted_at IS NULL)
※エイリアスに p を指定しているのに、テーブル名の先頭文字 o をエイリアスにされているが気になるけど。。。
これは、こちらの指定した DQL から Doctrine が SQL を生成する際に、
指定されたテーブルを順番に o1, o2, o3, … と再指定しているためだった。
その o も、恐らく、テーブル名の頭文字を取っていると思われる。
OpenPNE3 の場合、テーブル接頭辞を付けているため
全テーブルが op_ で始まるのよね。
Doctrine が NULL を探しているのに対して、
データ側は ‘0000-00-00 00:00:00’ という値であるため
スルーされていた。
上記 データ挿入→CSV から Null を放り込む方法 を用いて
値を Null にしてやることで、ちゃんとデータを取得できるようになった。
- $result = $this->createQuery('p')
- ->andWhere('p.deleted_at = ?', '0000-00-00 00:00:00')
- ->execute();
これで一応拾ってくることはできた。
とりあえずはこれでいくしかないけど。。。意味なーい!
いつか解明しなければ。。。
(やっと解明できた)
ちなみにテーブルエイリアスを付けないと、上記記述でも拾ってこない。
- // NG
- $result = $this->createQuery()
- ->andWhere('deleted_at = ?', '0000-00-00 00:00:00')
- ->execute();
必ずエイリアスをつける必要があります。
ただしこれはSELECT限定で、DELETEのときはエイリアスがなくても動くようです。アシアルブログ:Doctrineで論理削除を意識せずに扱う