最近使い始めたのでメモ
Entityとは
個々のレコードに対して処理を加えるためのもの。
これを定義しているとある一つのレコードのカラム同士を組み合わせて作るデータとかをひとまとめに管理できる。
実装のメリット
上記の通り、レコードに対して処理を行うのでその気になればこれがなくても欲しい情報を作れる。
(文字列連結とかで)
だが、それだともし変更があった際に修正箇所が散らばってしまう。
ということで変更点をひとまとめにできるのがメリットの一つ。
実装方法
・Model/Entity/以下にEntityファイルを作成
・対応させたいModelの初期化時にこのファイルを読み込ませる
・取り出したレコードに対して特定のプロパティでアクセスする
Model/Entity/以下にEntityファイルを作成
例えばarticlesテーブルのentityのファイル名はArticle.php
になる。
基本的にはテーブル名の単数形のキャメルケース。
説明のために、記事ページのURLをentityから取得する場合を考える。
仕様としては、
・URLは一律「 https://hoge.com/articles/ 」の末尾に記事IDを加えたもの。
・記事IDで一意にURLが決まるため、テーブルには記事IDしか保存されていない。
とする。
<?php
namespace App\Model\Entity;
use Cake\ORM\Entity;
class Article extends Entity
{
/**
* 記事URLを取得
*
* @return string
*/
protected function _getArticleUrl()
{
if (array_key_exists('id', $this->_properties)) {
return "";
}
return "https://hoge.com/articles/{$this->_properties['id']}";
}
}
ポイントとしては二点
・レコードのデータは$this->_properties['カラム名']
に入ってくる
・nullや空文字のカラムは上記配列のキーにも存在しなくなる
なのでもしnullになる可能性があるならarray_key_exists
で判定してやる必要がある。
(上記の例だと主キーなので不要だが説明のため記述した。)
対応させたいModelの初期化時にこのファイルを読み込ませる
Model/Table/Articles.phpのinitializeに下記を記述
$this->setEntityClass('App\Model\Entity\FsArticle');
取り出したレコードに対して特定のプロパティでアクセスする
ここまでやればあとは普通にアクセスできるようになる。
プロパティ名はEntityのメソッド名によって決まり、上記の例だと
$result = $this->find()->where(['id' => 1])->first();
//$url1も$url2も同じ値
$url1 = $result->articleUrl;
$url2 = $result->article_url;
でアクセスできる。
仮想プロパティーに関して
上記の場合、findで引っ張ってきたタイミングでは結果にarticle_urlが含まれない
$result = $this->find()->where(['id' => 1])->first();
debug($result); //これをしてもarticle_urlは確認できない。
これを嫌うなら、仮想プロパティを使えばfindした時点で宣言したプロパティが含まれるようになる。
やり方はEntityファイル内でprotectedの$_virtual
変数を定義し、このリストに含めたいプロパティを記述する。
(命名規則は仮想プロパティを使わない場合と同様)
<?php
namespace App\Model\Entity;
use Cake\ORM\Entity;
class Article extends Entity
{
protected $_virtual = ['article_url'];
/**
* 記事URLを取得
*
* @return string
*/
protected function _getArticleUrl()
{
if (array_key_exists('id', $this->_properties)) {
return "";
}
return "https://hoge.com/articles/{$this->_properties['id']}";
}
}
$result = $this->find()->where(['id' => 1])->first();
debug($result); //この時点でarticle_urlが確認できる。
entity内のメソッドが走るタイミング
基本的には定義したプロパティにアクセスした時点でメソッドが実行されるため、仮想プロパティを使ってるかどうかで実行タイミングが変わる。
(仮想プロパティはfindの裏側で指定したプロパティにアクセスしているため。)
仮に中の処理でエラーが起きている場合、
//仮想プロパティを使っている場合
$result = $this->find()->where(['id' => 1])->first(); //ここでエラー
$url = $result->article_url;
//仮想プロパティを使っていない場合
$result = $this->find()->where(['id' => 1])->first();
$url = $result->article_url; //ここでエラー
となる。