複数テーブルの連携 (5/5)
作成:2015-10-24 09:23
更新:2015-10-24 09:23
更新:2015-10-24 09:23
■MessagesTableクラスの用意
続いて、もう1つのテーブルクラス「MessagesTable」を作成しましょう。「Table」フォルダ内に、「MessagesTable.php」ファイルを作成して下さい。ソースコードは下のリスト欄のように記述しておきます。
このMessagesTableは、MembersTable側からhasManyで関連付けられる側のテーブルクラスになります。基本的に、「関連付けられる側」には、特別な処理などは必要ありません。ごく一般的なテーブルクラスとして作成してかまいません。
ただし、今回は、このMessagesTable側から、先ほどのMembersTable側へ関連付ける設定を用意してあります。それは、以下の部分です。
「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」と呼ばれる結合によって処理されます。両者の接続方式が、hasOneやhasManyなどとは違うのです。このため、joinTypeを明示的に'INNER'に設定しておきます。
また、その他に「buildRules」というメソッドが追加されています。これは、「ルールチェッカー(rules checker)」と呼ばれるオブジェクトを返すもので、「Messagesにmembers_idが用意されているか」を明示的にチェックするための仕組みです。(Membersテーブルには外部キーはありませんでしたから、このメソッドは用意されていなかったのです)
引数に渡されるRulesCheckerインスタンスの「add」メソッドを使い、ルールを追加します。引数には、RulesCheckerの「existsIn」というメソッドを使います。これは、第1引数の配列にあるフィールドが、第2引数のテーブルにすべて用意されているかチェックするものです。これで、ちゃんと用意されていればtrueがaddされますが、なければfalseがaddされ、ルールチェックでエラーになる、というわけです。
――とりあえず、これでモデル関係の作成はできました。アソシエーションそのものは、たったこれだけで使えるようになります。意外と簡単ですね!
この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」と呼ばれる結合によって処理されます。両者の接続方式が、hasOneやhasManyなどとは違うのです。このため、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され、ルールチェックでエラーになる、というわけです。
――とりあえず、これでモデル関係の作成はできました。アソシエーションそのものは、たったこれだけで使えるようになります。意外と簡単ですね!
(by. SYODA-Tuyano.)
※プログラムリストが表示されない場合
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 プログラミング入門」に戻る