libro
www.tuyano.com
初心者のためのCakePHP3 プログラミング入門

複数テーブルの連携 (5/5)

作成:2015-10-24 09:23
更新:2015-10-24 09:23

■MessagesTableクラスの用意

続いて、もう1つのテーブルクラス「MessagesTable」を作成しましょう。「Table」フォルダ内に、「MessagesTable.php」ファイルを作成して下さい。ソースコードは下のリスト欄のように記述しておきます。

このMessagesTableは、MembersTable側からhasManyで関連付けられる側のテーブルクラスになります。基本的に、「関連付けられる側」には、特別な処理などは必要ありません。ごく一般的なテーブルクラスとして作成してかまいません。

ただし、今回は、このMessagesTable側から、先ほどのMembersTable側へ関連付ける設定を用意してあります。それは、以下の部分です。
$this->belongsTo('Members', [
    'foreignKey' => 'members_id',
    'joinType' => 'INNER'
]);

belongsTo」は、「多対1(belongs to)」のアソシエーションを設定するためのものでしたね。先に述べたように、belongs toは、has manyの逆方向からのアソシエーションです。これを用意することで、「Memberのデータから、それに関連するMessageを得る」というだけでなく、「Messageのデータから、関連するMemberを得る」ということも行えるようになります。

このbelongsToメソッドも、使い方はhasManyと同じですね。第1引数には「Members」を指定します。第2引数には、foreignKeyとして「members_id」が指定されています。これは、先ほどのhasManyの場合とほぼ同じです。

重要なのはその後です。この他に、「joinType」という値が設定されていますね。belongs toは、SQLで「Inner Join」と呼ばれる結合によって処理されます。両者の接続方式が、hasOnehasManyなどとは違うのです。このため、joinTypeを明示的に'INNER'に設定しておきます。


■ルールチェッカーについて

また、その他に「buildRules」というメソッドが追加されています。これは、「ルールチェッカー(rules checker)」と呼ばれるオブジェクトを返すもので、「Messagesにmembers_idが用意されているか」を明示的にチェックするための仕組みです。(Membersテーブルには外部キーはありませんでしたから、このメソッドは用意されていなかったのです)
public function buildRules(RulesChecker $rules)
{
    $rules->add($rules->existsIn(['members_id'], 'Members'));
    return $rules;
}

引数に渡されるRulesCheckerインスタンスの「add」メソッドを使い、ルールを追加します。引数には、RulesCheckerの「existsIn」というメソッドを使います。これは、第1引数の配列にあるフィールドが、第2引数のテーブルにすべて用意されているかチェックするものです。これで、ちゃんと用意されていればtrueがaddされますが、なければfalseがaddされ、ルールチェックでエラーになる、というわけです。

――とりあえず、これでモデル関係の作成はできました。アソシエーションそのものは、たったこれだけで使えるようになります。意外と簡単ですね!

※プログラムリストが表示されない場合

AddBlockなどの広告ブロックツールがONになっていると、プログラムリスト等が表示されない場合があります。これらのツールをOFFにしてみてください。

●プログラム・リスト●

<?php
namespace App\Model\Table;

use App\Model\Entity\Message;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;

class MessagesTable extends Table
{

    public function initialize(array $config)
    {
        parent::initialize($config);

        $this->table('messages');
        $this->displayField('title');
        $this->primaryKey('id');

        $this->belongsTo('Members', [
            'foreignKey' => 'members_id',
            'joinType' => 'INNER'
        ]);
    }

    public function validationDefault(Validator $validator)
    {
        $validator
            ->add('id', 'valid', ['rule' => 'numeric'])
            ->allowEmpty('id', 'create');

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

        $validator
            ->allowEmpty('comment');

        return $validator;
    }

    public function buildRules(RulesChecker $rules)
    {
        $rules->add($rules->existsIn(['members_id'], 'Members'));
        return $rules;
    }
}
※関連コンテンツ

「初心者のためのCakePHP3 プログラミング入門」に戻る