はじめに
CakePHP3を学び始めたとき、
「MVCとはアプリの基本的な機能を3つに分けて設計する考え方」
と学んでも、実際実装するとなるとにどう書けばいいのかわかりませんでした。
なんでもかんでもコントローラーに書いちゃうのを卒業したい一心で色々と試してみて、
最近ようやくCakePHPのModel(例: UsersTable.phpとかUser.php)の使い方がざっくりと分かり始めてきたので、自分の頭の整理も兼ねて記事にしました。
未熟なところや誤りがありましたら、教えて頂けるととっても助かります!
対象
- ファットコントローラが良くないのはわかっているけど、どうしたらいいのかわからない方
- Modelがテーブルとエンティティに分かれている意味がわからない方
- そもそもMVCもよくわかんないって方
MVCとは?
掌田津耶乃さんの『CakePHP超入門』によると、MVCとは
アプリケーションの基本的な機能を3つに整理して設計する考え方です。
Model(モデル):データの管理を担当します。データベースにアクセスをしたりします。
View(ビュー):画面表示を担当します。
Controller(コントローラー):プログラム全体の制御を担当します。
とのことです。
3つの機能に分けることで、複数人でも開発がしやすかったり、エラー等の影響を小さくすることができるなどのメリットがあります。
Modelで何ができるのか?
Modelをざっくりといえばデータベース関係担当です。
じゃあデータ関係はModelに任せていいんだな〜とModelディレクトリを見てみると、
App\Model
|ー Table
|ー Entity
と分かれています。
このTableとEntity分かれているところが、まず1つ目の「( ˘ω˘ )?」となる箇所だと思います。
TableとEntityの違いとは?
リファレンスでは、
テーブルクラス
テーブルオブジェクトは特定のテーブルに保存されたエンティティーのコレクションへのアクセスを提供します。
エンティティークラス
エンティティーは個々の行やドメインオブジェクトを表します。エンティティーは保持するデータにアクセスして 操作するための永続的なプロパティーとメソッドを保有しています。
と説明されています。はて?( ˘ω˘ )という感じですが、
- テーブルクラスはDBのあるテーブルに保存されたレコードをオブジェクトとして扱いたい時に使うクラス
- エンティティークラスは1行の単体のデータをオブジェクトとしていじったりしたい時に使うクラス
とざっくりとした認識でひとまずは問題ないかと思います。
src/Model/Tableでできること
条件を指定して、テーブルに保存されたレコードを検索したい時などに使います。
例えば、usersテーブルに保存されているデータで、論理削除されていないレコード(is_deleted = false
)を全部引っ張ってくるメソッドを作成してみます。
// src/Model/Table/UsersTable.php 内で
class UsersTable extends Table {
// 中略
public function findIsNotDeleted() {
$isNotDeleted = $this->find()->where(['is_deleted' => false])->toList();
return $isNotDeleted;
}
}
これを、コントローラー側で
$isNotDeleted = $this->Users->findIsNotDeleted();
と呼び出すことで、論理削除されていないUsersテーブルのレコードを全て取得することができます。
モデルに書かずに、コントローラーで$this->Users->find()->where(略);
とすることもできますが、
- ファットコントローラーを避けたい
- 同じコードが何度も出てくる
場合、モデルのテーブルクラスに書くとすっきりしておすすめです。
src/Model/Entityでできること
DBに保存された、ある特定のレコードの値を更新したいときなどに使います。
例えば、ログインユーザーがそのアカウントを削除したいとき、そのユーザーの削除フラグを立てるメソッドを作成してみます。
// src/Model/Entity/User.php 内で
class User extends Entity {
// 中略
public function setIsDeleted() {
return $this->is_deleted = true;
}
}
これを、例えばコントローラーで
// ログインユーザーのUserオブジェクトを取得し、プロパティの値を書き換える
$user = $this->Users->get($user_id);
$user->is_deleted = $user->setIsDeleted();
$this->Users->save($user);
とsaveすることで、すでにDBのusersテーブルに保存されているレコードの一部を書き換えて保存することができます。
これらの応用で、テーブルクラスとエンティティクラスを組み合わせて
取得したテーブルオブジェクトの値を全て書き換えることができたりと便利なので、試してみてください。