Baby step - 思考と実験の足跡

日常のちょっとした、気になって試したこと集です。

Railsのfind_or_initialize_byにあたる関数をCakePHP3で作ってみた

idがあればupdateを、なければcreateをする

$data = ['name' => 'hoge'];
$entity = $table->findById($id)->first();

if ($entity != null) {
    $entity = $table->patchEntity($entity, $data)
} else {
    $entity = $table->newEntity($data);
}

こんな感じの分岐になってしまいます。

こういうコードを複数の画面で書いていたので、共通関数を作ってみました。

作った関数

# Behavior

# entityが存在する時はpatch, ない場合はnewでentityを返す
    public function newOrPatchEntity($entity, $data)
    {
        $table = TableRegistry::getTableLocator()->get($this->getTable()->getAlias()); # 呼び元のテーブル名を取得する
        if($entity != null) {
            $entity = $table->patchEntity($entity, $data);
        } else {
            $entity = $table->newEntity($data);
        }
        return $entity;
    }

このBehaviorを各モデルで呼べばOK.

以下のように呼び出せます。

$ntity = $table->newOrPatchEntity($entity, $data);

備考

わたしはTableクラスを継承したAppModelを作成し、 AppModelを全テーブルが継承するようにしています。

そのAppModelにてBehaviorを読み込んでいます。

懸念点

AppControllerAppVIewはCake側で作ってくれるのにAppModelだけ作ってくれないので、 もっと適切な構成があるのかも(引き続き調査中

参考記事