Railsと複合主キー

Railsから複合主キー*1を持つテーブルを扱う方法を調べることにする。
だいぶまえに調べたときは、いろいろと制約がありそうで、それきり無視していた。でも、勉強会でレガシー関連の話をしているうちに、これはちゃんと調べないといけないことがハッキリしたのだった*2。で、ちょっとググってみたら、なんだ、ちゃんと調べてくれている方*3がいるじゃないか。
ただ、その後に続く情報が少ないので、現在のバージョンを使って、自分なりに追試しながらまとめることにしようと思う。

まずはインストール

複合キーを扱うためのplugin*4 これはgemからインストールする。

gem install composite_primary_keys

もうひとつ、マイグレーション出来ないとつらいので、複合キー用の拡張も行う*5。だが、今日現在は一発インストールが出来ないみたいなので、あとで手動で入れることにして、とりあえずアプリフォルダ生成する。

rails testCPK
....
cd testCPK

ここで、マイグレーション拡張分をlibフォルダに作る*6

vim lib/composite_migrations.rb
ActiveRecord::ConnectionAdapters::ColumnDefinition.class_eval <<-'EOF'
  def to_sql
    if name.is_a? Array
      column_sql = "PRIMARY KEY (#{name.join(',')})"
    else
      column_sql = "#{base.quote_column_name(name)} #{base.type_to_sql(type.to_sym, limit)}"
      add_column_options!(column_sql, :null => null, :default => default)
    end
    column_sql
  end
EOF

ActiveRecord::ConnectionAdapters::ColumnDefinition.send(:alias_method, :to_s, :to_sql)		

最後に、config/environment.rbにrequireを追加する。

vim config/environment.rb  #末尾に2行追加する
....
# Include your application configuration below
require 'composite_primary_keys'  # モデルなどで複合キー使うための設定
require 'composite_migrations'   # マイグレーションで複合キー使うための設定

これでインストールは終わり。
と思っていたら、マイグレーションが通らない。
エラー箇所は“type_to_sql”の呼び出し。ん?と思って、Rails APIページから、“add_column”のshow sourceを見ても同じに見える。
分からなくなってきたので、Railsのソースに検索かけたら判った。オリジナルは“type_to_sql”なのだが、1.2系からは“base.type_to_sql”としなければならないようだ。直後に気がついたのだけど、実はhttp://errtheblog.com/post/16のコメント欄に同じことが載っていた。ちゃんと読めば良かった。

(つづく)

*1:CPK:Composite Primary Keyって言うらしい

*2:私のように企業内でRails使うことを考えると、実は死活問題かも知れない

*3:id:akmさん 2006-10-24 この検証の速さは凄いなぁ

*4:http://compositekeys.rubyforge.org/

*5:http://plugins.require.errtheblog.com/browser/composite_migration

*6:お試しなのでポチっとね。別にrubyのrequireパスに入れてもいいのだろうけど。