CakePHP3から新しく追加されるEntityクラスの簡単なまとめ
環境構築についてはCakePHP dev-3 + Windows7 + IIS + MySQLの環境構築を参照
- 概要
- ファイル名・クラス名
- Getter と Setter
- Eager loading と Lazy loading
- その他
概要
- 2.xまでのModelクラスは、3.xではTableクラスとEntityクラスに分離される
- Tableクラスは主に下記のような機能を有する(2.xまでのModelクラスと機能的にはほぼ同じ)
- データのCRUD
- アソシエーション
- バリデーション
- Entityクラスはクエリ結果の各レコードにアクセスするためのクラス
namespace App\Model\Table;
use Cake\ORM\Table;
class ArticlesTable extends Table {
public function initialize(array $config) {
$this->belongsTo('Users');
$this->hasMany('Comments');
}
public function index() {
$query = $articles->find();
// クエリ結果のデータ型は配列ではなくオブジェクト
// フェッチで結果を取得
foreach ($query as $row) {
echo $row->title;
// or
echo $row->get('title');
// アソシエーションテーブルから取得
// UserEntityクラスは$row->userに相当
echo $row->user->name
foreach ($row->comments as $comment)
// CommentEntityクラスは$commentに相当
echo $comment->comment;
}
}
}
ファイル名・クラス名
- ファイル名・クラス名ともに対応するTableクラスの単数形
- 別のクラス名のEntityクラスを指定したい場合は、Tableクラスのinitializeメソッドで指定
Getter と Setter
namespace App\Model\Entity;
use Cake\ORM\Entity;
class Article extends Entity {
// フィールド名の先頭に'get'をつける
public function getTitle($title) {
return ucwords($title);
}
// フィールド名の先頭に'set'をつける
public function setTitle($title) {
// set(key, value)で$_properties配列にデータをセット
$this->set('slug', Inflector::slug($title));
return $title;
}
// 複数フィールドの値を加工して取得したい場合、メソッド名のget,setの後ろは自由
public function getFullName() {
// クエリで取得した値、もしくはset()でセットした値を$_propertiesから取得
return $this->_properties['first_name'] . ' ' .
$this->_properties['last_name'];
}
}
Eager loading と Lazy loading
- Eager loading = 一括取得
- Lazy loading = 都度取得
- 両者のメリット・デメリットについては割愛
// Eager loading はアソシエーションによるデータの一括取得
// Lazy loading はEntityのGetterでアソシエーションテーブルのデータを取得
namespace App\Model\Entity;
use Cake\ORM\Entity;
use Cake\ORM\TableRegistry;
class Article extends Entity {
public function getComments() {
// Commentsテーブルクラスをインスタンス化
$comments = TableRegistry::get('Comments');
// Articleのidと紐づくCommentsデータを取得
return $comments->find('all')
->where(['article_id' => $this->id])
->all();
}
}
$article = $this->Articles->findById($id);
// $article->commentsで上記のgetCommentsを実行
foreach ($article->comments as $comment) {
echo $comment->body;
}
その他
- 関数の再利用
- バリデーションエラー
- 仮想フィールドの設定
- 隠しフィールの設定
関数の再利用
- Traitを使用
// SoftDelete/Model/Entity/SoftDeleteTrait.php
namespace SoftDelete\Model\Entity;
trait SoftDeleteTrait {
public function softDelete() {
$this->set('deleted', true);
}
}
namespace App\Model\Entity;
use Cake\ORM\Entity;
use SoftDelete\Model\Entity\SoftDeleteTrait;
class Article extends Entity {
use SoftDeleteTrait;
}
バリデーションエラー
// すべて取得
$errors = $user->errors();
// フィールドを指定して取得
$errors = $user->errors('password');
// メッセージをセット
$user->errors('password', ['Password is required.']);
仮想フィールドの設定
Entityクラスの$_virtual
プロパティにセット
namespace App\Model\Entity;
use Cake\ORM\Entity;
class User extends Entity {
protected $_virtual = ['full_name'];
}
...
// テーブルオブジェクトからセットする場合、virtualProperties()を使用
$user->virtualProperties(['full_name', 'is_admin']);
隠しフィールドの設定
Entityクラスの$_hidden
プロパティにセット
namespace App\Model\Entity;
use Cake\ORM\Entity;
class User extends Entity {
protected $_hidden = ['password'];
}
...
// テーブルオブジェクトからセットする場合、hiddenProperties()を使用
$user->hiddenProperties(['password', 'recovery_question']);