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 を使えばよいことまで確認できました。最初はフレームワークの最小限のメソッドだけ使って、あとは徐々に置き換えかなあと。

コメントをどうぞ

メールアドレスが公開されることはありません。

次のHTML タグと属性が使えます: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <img localsrc="" alt="">