LoginSignup
70
72

More than 5 years have passed since last update.

CakePHP3まとめ(Entityクラス編)

Posted at

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']);
70
72
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
70
72