CakePHPで2つのテーブルを連結させる

さて、極悪テーブル命名規則 T100,T200,T300 を magazines, publishers, users に変えることができたので、今度はテーブルの連結をしてみます。

<!-- views/magazines/index.ctp -->
<h2>雑誌一覧</h2>
<table>
	<tr>
		<td>id</td>
		<td>name</td>
		<td>publisher_id</td>
		<td>publisher_id</td>
	</tr>
<?php foreach($Magazines as $item) : ?>
	<tr>
		<td><?php echo $item['Magazine']['id'] ?></td>
		<td><?php echo $item['Magazine']['name'] ?></td>
		<td><?php echo $item['Magazine']['T200id'] ?></td>
		<td><?php echo $item['Magazine']['publisher_id'] ?></td>
	</tr>
<?php endforeach ; ?>
</table>

のように、publisher_id を表示させたって意味がないわけで、出版社名(Publisher.name)を表示させたい訳です。

<!-- views/magazines/index.ctp -->
<h2>雑誌一覧</h2>
<table>
	<tr>
		<td>id</td>
		<td>name</td>
		<td>publisher_id</td>
		<td>publisher_id</td>
	</tr>
<?php foreach($Magazines as $item) : ?>
	<tr>
		<td><?php echo $item['Magazine']['id'] ?></td>
		<td><?php echo $item['Magazine']['name'] ?></td>
		<td><?php echo $item['Magazine']['T200id'] ?></td>
		<td><?php echo $item['Magazine']['publisher_id'] ?></td>
		<td><?php echo $item['Publisher']['name'] ?></td> ★
	</tr>
<?php endforeach ; ?>
</table>

みたいに使えればいいですよね。使えるのかな?

という訳で、ひとつの雑誌(magazine)は、出版社(publisher)に属するということで、Magazine モデルを書き換えます。

<!-- models/magazine.php -->
<?php
class Magazine extends AppModel
{
	var $name = 'Magazine';
	var $useTable = 'T100';
	var $virtualFields = array(
		'publisher_id'=>'T200id' );

	var $belongsTo = array('Publisher' =>
		array(
			'className' => 'Publisher',
			'conditions' => '',
			'order' => 'Magazine.id ASC',
			'foreignKey' => 'T200id' ));
}
?>

この外部キーの書き方はいくつかあるのですが、$belongsTo と $hasMeny は双方向なのでどちらか決めで使えばいいんでしょう。

こうすると、先の index.ctp が動きます。生成される SQL を見ると、

SELECT 
 `Magazine`.`id`, 
 `Magazine`.`name`, 
 `Magazine`.`T200id`, 
 `Magazine`.`price`, 
 (T200id) AS `Magazine__publisher_id`, 
 `Publisher`.`id`, 
 `Publisher`.`name` 
FROM `T100` AS `Magazine` 
 LEFT JOIN `T200` AS `Publisher` ON (`Magazine`.`T200id` = `Publisher`.`id`) 
WHERE 1 = 1 
 ORDER BY `Magazine`.`id` ASC 

となっているので、left join が使われていますね。なるほど。

残念ながら $virtualFields で別名定義をしたカラム名は、$belongsTo では使えないようで、あの不思議な T200id というカラム名が出てきますが、まぁ、良しとしましょう。適当なヘルパー関数なりを作れば、このあたりの設定も楽になると思います。$virtualFields が連想配列なので、逆引きして value から key を取り出せばよいので。

カテゴリー: 雑談, CakePHP パーマリンク

CakePHPで2つのテーブルを連結させる への2件のフィードバック

  1. konica のコメント:

    お、把握。
    勉強になる(´・ω・)ス
    引き続きヲチ

    • masuda のコメント:

      ひとまず、テーブルの連結は最悪 Model::query を使えばよいことまで確認できました。最初はフレームワークの最小限のメソッドだけ使って、あとは徐々に置き換えかなあと。

コメントは停止中です。