CakePHP2から5に乗り換えた話 〜エンティティは使える子だった〜

AIの画像生成で「entity」と入れたらこうなった

この記事を三行にまとめると

便利な存在だなと思いました
ヘルパー以上のことができる
もっと上手く活用していきたい
CakePHP2系まではデータベースのテーブル関係のファイルはModel一つだけでしたが、3以降はTableとEntityという二つのクラスで構成されるようになりました。

僕の中のざっくりしたイメージだとTableが2系のときのModelに相当するもので、Entityはその補助的なものという位置づけです。Tableでデータベースとあれこれやり取りして、Entityは一つのレコードの中の処理をいろいろと行うみたいな感じですかね。

以前CakePHP3を触ったときにこのTableとEntityはどう使い分けたら良いのか分からん的なことをブログで書いたんですが、多少使い方が分かってきたら想像以上にEntityってのは便利な存在だなと思いました。

CakePHP3を触ってみました 〜tableとentityはどう使い分けたらええねん〜

例えばデータベースからデータを取ってきてビューに渡す前にデータの中身をいろいろと整形したい場合、CakePHP2はコントローラーかモデルで一回データをforeachで回して整形したデータを入れ直すみたいな処理が必要でした。

ちょっと良い例が出てこないんですけど、例えばこんな感じのjsonデータがデータベースに格納されているとします。

{'sun': 10, 'mon': 25; 'tue': 40}

曜日ごとに何らかのデータを数字として持っているみたいな感じです。

これの合計をビューで出力したい場合、よくあるやり方としてはコントローラーかモデルで合計値を算出して入れるか、ビューでヘルパーに合計値を算出する処理を書いておいてそれを呼び出すかだと思います。

コントローラーで処理してビューで出力する場合
// コントローラー
$data = $this->Model->find('all');

foreach($data as &$val) {
  $val['Model']['week'] = json_decode($val['Model']['week'], true);
  $val['Model']['sum'] = array_sum($val['Model']['week']);
}

$this->set(compact('data'));

// ビュー
<?php foreach($data as $val) : ?>
  <?= $val['Model']['sum'] ?>
<?php endforeach ?>

ビューのヘルパーで処理する場合
// コントローラー
$data = $this->Model->find('all');
$this->set(compact('data'));

// ビュー
<?php foreach($data as $val) : ?>
  <?= $this->Helper->sum($val['Model']['week']) ?>
<?php endforeach ?>

// ヘルパー
public function sum($val) {
  $val = json_decode($val, true);
  return array_sum($val);
}

でもEntityの登場によってこの辺のわずらわしさが解消されました。自分で一回foreachで回して……なんてことをしなくてもEntityの中にその処理を書いておけばいつでもどこでも呼び出せます。

// コントローラー
$data = $this->find()->all();
$this->set(compact('data'));

// エンティティ
public function _getSum() {
  $val = json_decode($this->week, true);
  return array_sum($val);
}

// ビュー
<?php foreach($data as $val) : ?>
  <?= $val->sum ?>
<?php endforeach ?>

一見するとヘルパー作るやり方と大差なくね?って思うかもしれませんけど、ヘルパーは基本的にビューの中でのみ使えるのに対して、エンティティはコントローラー、モデル、ビューのどっからでもいつでも好きに呼び出せるという利点があります。「_getXx」という関数を作っておけば、「$val->xx」で呼び出し可能です(関数名の方のXxは先頭が大文字)

それだけではなく「_set〇〇」という関数でデータ登録用の処理も作れるので、データ保存前にやっておきたい処理があればこれを利用すると良いと思います。他にもフィールドごとにデータが書き換えられているか判定したりうっかり上書きしたくないフィールドにプロテクトをかけたりヘルパー以上のことができるので、僕もまだ完璧に使いこなせているわけではないんですけどこれはかなり便利だと思います。

取得したデータを加工したり保存前に整形したい場合って結構あるんですけど、コントローラーでやったりモデルでやったりヘルパーでやったりしてるとコードがごちゃごちゃしてきちゃうんですよね。でもエンティティにひとまとめできるようになったおかげでだいぶその辺がすっきりしました。

これはぜひとももっと上手く活用していきたい機能ですね。

その他のCakePHP5に乗り換えた話はこちら
ようやくのぼりはじめたはてしなく遠い開発坂
 もしかしたら何か関連しているかも? 
 質問や感想などお気軽にコメントしてください