2
6

More than 3 years have passed since last update.

CakePHPで論理削除

Last updated at Posted at 2020-05-06

論理削除のメリットデメリット

  • ユーザーからその存在を隠蔽したいが、データとしては残しておきたい (例えば、業務事情により当該データを使用禁止にしたいが、一時的なのですぐに元に戻せるようにしたい場合)
  • 誤って削除した場合に備え、すぐにデータを復元できるようにしておきたい

参考

記事の論理削除

CakeDCを用いて論理削除を実装した。
論理削除
DBでdeletedカラムをデフォルトで0に設定して、
delete関数が走った時に、deletedカラムに1が立つように実装すれば良い。

SELECT文では検索した場合はdeleted=0が勝手に条件で入り、論理削除されたデータは表示されなくなる。

論理削除関数

  public function exists($id = null) {
        if ($this->Behaviors->loaded('SoftDelete')) {
            return $this->existsAndNotDeleted($id);
        } else {
            return parent::exists($id);
        }
    }

    public function delete($id = null, $cascade = true) {
        $result = parent::delete($id, $cascade);
        if ($result === false && $this->Behaviors->enabled('SoftDelete')) {
           return (bool)$this->field('deleted', array('deleted' => 1));
        }
        return $result;
    }

上記のように実装したが、実はdelete()はsoftdeleteで上書きされていて、消去ではなくupdateという形になっているらしい。
また、deletedというカラム名があればそこに1を立ててくれるようになっている。
なくても動くものはコメントアウトした。


    public function exists($id = null) {
        if ($this->Behaviors->loaded('SoftDelete')) {//ちゃんとプラグインがあるとき
            return $this->existsAndNotDeleted($id); ////普通の存在チェックだとレコードあるかないかで判断してしまうので、論理削除バージョンの存在チェックが必要
        } 
        // else {//こいつはなくても論理削除は動く
        //     return parent::exists($id); //おそらく、ここでのparentはAppModel(デフォルトのexitsを読んでる)
        // }
    }

    // public function delete($id = null, $cascade = true) { //cascadeがtrueだと関連するテーブルのレコードも消去される
    //     $result = parent::delete($id, $cascade); //消去されちゃうと心配かもしれないが上書きされているっぽい
    //     if ($result === false && $this->Behaviors->enabled('SoftDelete')) {
    //        return (bool)$this->field('deleted', array('deleted' => 1)); //なぞ、falseじゃなくてtrueがかえるらしい
    //     }
    //     return $result;
    // }

これで、SoftDeleteBehaviorで定義されている
デフォルトのカラム名を変更できる。

public $actsAs = ['Utils.SoftDelete'=>['削除フラグ名'=>'削除日時名']];
//実例
public $actsAs = ['SoftDelete'=>['deleted2'=>'deleted_date2']];

Behavior
モデル間で共通して利用したい機能などをまとめることができる。(controllerでいうコンポーネント的な?)
これを利用すると継承をする必要がなくなる。
ファイルはapp/Model/Behaviorにおく。

Modelのクラスメソッド
appModelの継承先のModelにおそらく、findとかdeleteメソッドが定義されている(クラスメソッド)。PostModelでdeleteをかくことで上書きできる。はず。

スコープ定義演算子 (::)
parent,self,static

Curlコマンドが便利そう
気軽にhttpリクエス、ファイルダウンロードとかできる。

get
curl localhost:8080/api/json

標準出力せず、getで取得したデータをファイルに書き込める。
今回githubにあるファイル単体をダウンロードするのに使った。
curl localhost:8080/api/json -o

豆知識

  • jsってint型ない。かわりにnumber型がある(整数または浮動小数点数)
2
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
6