複数テーブルの連携 (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 プログラミング入門」に戻る