MySQL 3.23 な環境で CakePHP の hasAndBelongsToMany を利用する
そもそもですが,CakePHP は MySQL 4.0 以上が対象らしいです.
ただ,公式のドキュメントは見つかっていませんが……
それでも,MySQL 3.23 な環境で CakePHP を使って,なおかつ hasAndBelongsToMany も使いたい場合の対処法です.
MySQL 3.23 な環境では,hasAndBelongsToMany を使うとき,SQL のエラーが出ます.具体的には JOIN に失敗しています.
このとき CakePHP は以下のような SQL 文を発行します.
SELECT `Tag`.`id`, `Tag`.`tag`
FROM `tags` AS `Tag`
JOIN `posts_tags` ON `posts_tags`.`post_id` = '2'
AND `posts_tags`.`tag_id` = `Tag`.`id`
WHERE 1 = 1
MySQL のリファレンスにあるように,JOIN は MySQL 4.0.11 以降で対応なので,この JOIN を INNER JOIN にしてあげればいいわけです.
- ref.: MySQL AB :: MySQL 4.1 リファレンスマニュアル :: 6.4.1.1 JOIN 構文
http://dev.mysql.com/doc/refman/4.1/ja/join.html
注意:INNER JOIN 構文で join_condition を使用できるのは、MySQL 3.23.17 以降に限られます。同様に、JOIN と CROSS JOIN に関しても、MySQL 4.0.11 以降でのみ条件を指定できます。
ちょうど昨日 CakePHP の最新版 (1.1.14.4797) がリリースされたので,この最新版と,その前のバージョン (1.1.13.4450) での修正箇所を挙げておきます.
- 1.1.14.4797 の場合
cake/libs/model/datasources/dbo_source.php の 1051 行目を修正します.
--- cake_1.1.14.4797-orig/cake/libs/model/datasources/dbo_source.php 2007-04-06 04:21:05.000000000 +0900
+++ cake_1.1.14.4797/cake/libs/model/datasources/dbo_source.php 2007-04-06 08:46:09.015389000 +0900
@@ -1048,6 +1048,7 @@
'joins' => array(array(
'table' => $joinTbl,
'alias' => $joinAssoc,
+ 'type' => 'INNER',
'conditions' => array(
array("{$joinAlias}.{$assocData['foreignKey']}" => '{$__cakeID__$}'),
array("{$joinAlias}.{$assocData['associationForeignKey']}" => '{$__cakeIdentifier['."{$alias}.{$linkModel->primaryKey}".']__$}')
- 1.1.13.4450 の場合
cake/libs/model/datasources/dbo_source.php の 1043 行目を修正します.
--- cake_1.1.13.4450-orig/cake/libs/model/datasources/dbo_source.php 2007-02-03 11:55:49.000000000 +0900
+++ cake_1.1.13.4450/cake/libs/model/datasources/dbo_source.php 2007-04-06 09:13:16.018886000 +0900
@@ -1040,7 +1040,7 @@
}
$sql .= ' ' . join(', ', am($this->fields($linkModel, $alias, $assocData['fields']), $joinFields));
$sql .= ' FROM ' . $this->fullTableName($linkModel) . ' ' . $this->alias . $this->name($alias);
- $sql .= ' JOIN ' . $joinTbl;
+ $sql .= ' INNER JOIN ' . $joinTbl;
$joinAssoc = $joinTbl;
上記の修正はあくまで,hasAndBelongsToMany を使いたい場合で,そのほかの項目はあまりテストしていませんのでご注意を.
可能であれば,MySQL 4.0.x にアップデートするのが一番だと思います.