#05 Model を使ってみる

モデル

データベースに関する機能は、「モデル(Model)」に実装されている。

CakePHP3では、「テーブル」と「エンティティー」という2種類の Model を使用して、データベースを操作する。

テーブル

データへのアクセスに必要な情報を提供する。レコードの保存・既存データの編集/削除などを行う。

エンティティー

「エンティティー」は個々のレコードを意味する。レコードレベルの振る舞いや機能の定義をする。

当初は「テーブル」、「エンティティ」ともに自動生成されたコードを使用するため、自らコーディングしなくてもモデルが使用できる。

テーブルの作成

データベースにテーブルを用意していく。

今回、MySQL で「heroes」というテーブルを作成する。

テーブルの名前は複数形になっているが、複数形で命名するのが基本。もちろん、複数形でなくとも作成し運用することは可能。

項目は以下の4つ。

  1. id : プライマリーキーとなる整数。連番。
  2. name : 超人の名前を格納するテキストフィールド。
  3. power : 超人強度を格納する整数のフィールド。
  4. country : 出身国を格納するテキストフィールド。

今回は phpMyAdmin で作成した。

bake コマンドで Model を作成

テーブルを作成したらコマンドを使用して Model を自動生成する。CakePHP3 では、テーブルの構造をもとに Model のソースコードを自動生成し、簡単に作成することができる。

コマンドプロンプトを起動し、「cd」コマンドで「\htdocs\chococake」に移動。

C:\Users\username>cd C:\Bitnami\wampstack-5.6.29-1\apache2\htdocs\chococake

以下のコマンドを実行。

C:\Bitnami\wampstack-5.6.29-1\apache2\htdocs\chococake>bin\cake bake model heroes

以下のように表示され、Model が生成される。


Welcome to CakePHP v3.4.12 Console
---------------------------------------------------------------
App : src
Path: C:\Bitnami\wampstack-5.6.29-1\apache2\htdocs\chococake\src\
PHP : 5.6.29
---------------------------------------------------------------
One moment while associations are detected.

Baking table class for Heroes...

(以下略)

エンティティークラス

「\htdocs\chococake\src\Model\Entity」内に「Hero.php」というファイルが生成されている。

テーブル名は「heroes」と複数形だったが、エンティティーは単数形で生成される。

<?php
namespace App\Model\Entity;

use Cake\ORM\Entity;

/**
 * Hero Entity
 *
 * @property int $id
 * @property string $name
 * @property int $power
 * @property string $country
 */
class Hero extends Entity
{

    /**
     * Fields that can be mass assigned using newEntity() or patchEntity().
     *
     * Note that when '*' is set to true, this allows all unspecified fields to
     * be mass assigned. For security purposes, it is advised to set '*' to false
     * (or remove it), and explicitly make individual fields accessible as needed.
     *
     * @var array
     */
    protected $_accessible = [
        '*' => true,
        'id' => false
    ];
}

_accessible プロパティ

エンティティーに記述があるのは、「_accessible」 プロパティのみ。

「_accessible」 プロパティはテーブルへのアクセスを保護している。

データベースへのアクセスが「*」で許可され、「id」フィールドへのアクセスが「false」となり保護されている。

テーブルクラス

「\htdocs\chococake\src\Model\Table」内に「HeroesTable.php」というファイルが生成されている。エンティティーが単数形だったのに対し、テーブルクラスはテーブル名そのまま複数形で生成されている。

<?php
namespace App\Model\Table;

use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;

/**
 * Heroes Model
 *
 * @method \App\Model\Entity\Hero get($primaryKey, $options = [])
 * @method \App\Model\Entity\Hero newEntity($data = null, array $options = [])
 * @method \App\Model\Entity\Hero[] newEntities(array $data, array $options = [])
 * @method \App\Model\Entity\Hero|bool save(\Cake\Datasource\EntityInterface $entity, $options = [])
 * @method \App\Model\Entity\Hero patchEntity(\Cake\Datasource\EntityInterface $entity, array $data, array $options = [])
 * @method \App\Model\Entity\Hero[] patchEntities($entities, array $data, array $options = [])
 * @method \App\Model\Entity\Hero findOrCreate($search, callable $callback = null, $options = [])
 */
class HeroesTable extends Table
{

    /**
     * Initialize method
     *
     * @param array $config The configuration for the Table.
     * @return void
     */
    public function initialize(array $config)
    {
        parent::initialize($config);

        $this->setTable('heroes');
        $this->setDisplayField('name');
        $this->setPrimaryKey('id');
    }

    /**
     * Default validation rules.
     *
     * @param \Cake\Validation\Validator $validator Validator instance.
     * @return \Cake\Validation\Validator
     */
    public function validationDefault(Validator $validator)
    {
        $validator
            ->integer('id')
            ->allowEmpty('id', 'create');

        $validator
            ->requirePresence('name', 'create')
            ->notEmpty('name');

        $validator
            ->integer('power')
            ->requirePresence('power', 'create')
            ->notEmpty('power');

        $validator
            ->requirePresence('country', 'create')
            ->notEmpty('country');

        return $validator;
    }
}

initialize メソッド

「initialize」メソッドで初期化を行っている。

$this->setTable('heroes');

テーブルの設定。使用するデータベースのテーブルを指定している。この部分を変更すれば独自の他のテーブルを指定することが可能。

$this->setDisplayField('name');

指定してある「name」は、レコードのタイトルとして使われるフィールド。

$this->setPrimaryKey('id');

プライマリーキーとなっているフィールドを設定。テーブル側でも項目をプライマリーキーに設定しておく必要あり。
※今回はテーブル作成時に設定済みのはず。

validationDefault メソッド

テーブル各フィールドのバリデーションの設定を行うためのメソッド。

->allowEmpty

空の値を許可する。

->notEmpty

空の値を許可しない。

「add」メソッドを使用して、新たにバリデーションの設定を加えることも可能。

CakePHP の一覧