CakePHP1.2 joinTableの命名長さ制限

投稿者 aoki 2009 年 3 月 17 日 – 10:21 PM -

CakePHP1.2になり、関連テーブル(HABTMなど)の保存が簡単になった。
$this->data にしっかりとデータセットすれば 
$this->Model->save(); とすれば、
すべての関連データを関係するテーブルに自動的に保存してくれます。  

ところが、、、、うまく行かない。。。のです。
原因は、joinTableの識別子名が長くなりすぎたことでした。

使用しているデータベースは PostgrSQL8.1ですが、
識別子の長さが63ビットまでとなっていました。

元のテーブル(HABTM)
tbl0010members
tbl0020business_categories
命名規則に沿ったjoinTableは
tbl0010members_tbl0020business_categories

この時点では文字数制限に触れてなさそうなのですが、
CakePHP1.2で自動生成されるSelect文を良く見ると、
以下の様なエイリアス名を自動生成していました。

SQL:
  1. "Tbl0010membersTbl0020businessCategory"."tbl0020business_category_id" AS
  2. "Tbl0010membersTbl0020businessCategory__tbl0020business_category_id"

エイリアス名は66文字になっており、
このSQL文を走らせるとエラーになります。

PostgreSQLの設定値 NAMEDATALEN を変更し、
コンパイルしなおせばこの制限値を変更できるのですが、
yumでインストール管理しているので避けたい。

ということで、joinTableそのものは、命名規則に沿わせておいて、
更新可能な view を用意して、代理させました。
(ちなみに1.1では命名規則どおりで動くきます。)

更新可能なviewの名前を
members_business_categories
とすると、追加のSQL文は以下の通り。

SQL:
  1. DROP VIEW members_business_categories;
  2.  
  3. CREATE VIEW
  4. members_business_categories
  5. AS
  6. SELECT * FROM tbl0010members_tbl0020business_categories;
  7.  
  8. CREATE RULE members_business_categories_ins
  9. AS ON INSERT TO members_business_categories
  10. DO INSTEAD
  11. INSERT INTO tbl0010members_tbl0020business_categories
  12. VALUES ( new.tbl0010member_id,new.tbl0020business_category_id);
  13.  
  14. CREATE RULE members_business_categories_del
  15. AS ON DELETE TO members_business_categories
  16. DO INSTEAD
  17. DELETE FROM tbl0010members_tbl0020business_categories
  18. WHERE tbl0010member_id=old.tbl0010member_id AND
  19. tbl0020business_category_id=old.tbl0020business_category_id;

モデルのアソシエーション定義で、
上記のviewをjoinTableとwithに設定

PHP:
  1. var $hasAndBelongsToMany = array(
  2. 'Tbl0020businessCategory'=>array(
  3. 'joinTable'=>'members_business_categories',
  4. "with"=>"MembersBusinessCategory"),
  5. );

これで、かなりの文字数を稼げました。

テーブル番号を振るローカル命名規則が仇になった。。。
というこでしょうね(ーー;)


Tags:
カテゴリー: IT一般, PHP | トラックバックURL

コメントをどうぞ