preload
1月 10

DBのマスタメンテナンスツールを手軽に作りたいなーと思い、O/Rなツールをいろいろと試してみている。仕事だと既存のアレな感じのDBも面倒を見なければならず、どうすれば楽ができるかなと模索中。
で、CakePHPをちょっといじってみた。最新の 1.1.12.4205 を試用。日本語のマニュアルもあるよ。
アーカイブを拾ってきてひとまず DocumentRoot の下に設置。app/config/database.php で DB の接続設定。これだけでとりあえず準備完了。ルートディレクトリ(index.php)にブラウザからアクセスすれば接続できてるよーって画面が見える。
CakePHP だと、同梱されている bake コマンドを使って、Model, View, Controller の Scaffolds がさくさく作れる。

$ php cake/scripts/bake.php
___ __ _ _ ___ __ _ _ __ __ __ _ _ ___
| |__| |_/ |__ |__] |__| |__] |__] |__| |_/ |__
|___ | | | _ |___ | | | | |__] | | | _ |___
—————————————————————
Baking…
—————————————————————
Name: app
Path: /usr/local/apache2/htdocs/cake/app
—————————————————————
[M]odel
[C]ontroller
[V]iew
What would you like to Bake? (M/V/C)
>

既存DBのメンテナンスツールを作ることを想定しているので、いくつか使い勝手を確認してみる。

テーブル名、カラム名に制約はないか
デフォルトだとあるけど、変更できる。たとえば、テーブル名はクラス名単数形 + ‘s’ でないとダメ、単語間区切りは大文字 <=> アンダースコア ‘_’ で置き換え(AddressBookクラスならaddress_books)、とか。これは bake で Model を生成するときにテーブル名を手動で指定してやればOK。primary key はカラム名 id の必要があるが、これは app/models/ の下に吐かれる Model クラス中で var $primaryKey = ‘address_book_id’; などとしてやれば OK。
Given your model named ‘AddressBook’, Cake would expect a database table named ‘address_books’.
Is this correct? (y/n)
[y] > n
What is the name of the table (enter “null” to use NO table)?
> address_book
Model間の関連(アソシエーション)は定義できるか
Model 間の関連も対話式に定義できる。hasOne, hasMany, belongsTo, hasAndBelongsToMany から選ぶ感じ。スキーマ中に外部キー制約が付けてあれば自動検出してくれるし、制約なんて付けてないアレなスキーマでも、手動設定できる。手動設定するときは関連先をテーブル名でなくクラス名(モデル名)で指定すること。
複合キーのModelは定義できるか
これが無理っぽい。思わぬところではまった。

たとえば、CustomerHasManyAddressBooks なアソシエーションがあるとして、customer は customers_id が PK、address_book は customers_id と address_book_id の複合キーが PK であるとすると、前者は問題なく定義できるのだが、後者は定義できないようだ。Model 中で $primaryKey = array(‘customers_id’, ‘address_book_id’) などとやってもダメ。CakePHP, multi, primary keyとかでググると、本家のtracに当たった。このチケットとかこことかこの辺を見ると、クローズになってるのか、未対応なのか、できそうな、まだできなさそうな、微妙なステータス。
言葉を変えて composite primary keys などで IRC ログを漁ってみると、どうやら対応してないし、まだ対応する予定も無いような発言も見える(この人は中の人だろうか)。RoR とかでも別の PK 扱いできるインクリメンタルなカラムをつくるというのが現実解ぽいし、複合キーは使わないのが良いのかな。
そもそもCakePHPだと各レコードのURLでPKをそのまま使うという設計になっているようで、複合キーを入れると、キーを複合した文字列を作ったり分割したりという処理が必要になってくる。まだ一部しか見られていないが、これが大変、ということだろうか。複合キーを使う時点で、個々のIDの体系に縛られる設計になってしまうし、こういった関連は外に切り出してしまうのがベターなのかもしれない。
でも既存のDBをそこまで梃入れする元気も無いし、やんなきゃやんないで話は進まないしと言うジレンマ。なんかうまい楽な方法はないものか。


関連していそうなエントリ:

4 Responses to “CakePHPで複合キーは使えない?”

  1. sdozono Says:

    どうしても id フィールドは作りたくない、という場合には、http://qcodo.com がよさそうです。”Qcodo even allows tables to have multiple-column primary keys. However, only limited functionality will be generated for tables that have multiple primary keys. “とあります。

  2. yosuke Says:

    sdozono さん、コメントありがとうございます。
    qcodo ですか、これは知りませんでした。
    早速使ってみましたが、スキーマの定義にとらわれず、設定ファイルで関連定義できる緩さ、ロジックは個別で書けるけどテンプレ用意してビューまで自動生成って辺りが絶妙な感じです。まさしく求めていたものかも!また、こちらでレビューエントリ書きたいとおもいます。
    ありがとうございました。
    # URLが間違っていたので修正させていただきました (_O_)

  3. Persistence is Power Says:

    qcodoを試してみた

    「CakePHP で複合キーは使えない?」というエントリを書いたところ、sdozonoさんという方からコメントをいただいた。
    どうしても id フィールドは作りたくない、という場合には、http://qcodo.com がよさそうです。”Qcodo even allows tables to have multiple-column p…

  4. Neo Inspirations Says:

    アソシエーションの限界?

    Modelを作ってるとき 泥沼にはまってしまったのでメモメモ。
    若干DB規約に沿っていないものを使っているということで、
    これのせいかなと勘違いして何度もpostsテーブルとusersテーブル…

Leave a Reply