Rails 2.2で既存のテーブルを使う

既存のテーブルをRailsで使う場合の鬼門は

・テーブル名称が'Rails-Aware'ではない(複数形を使っているとは限らない)
・プライマリキーの名称(列名)が'Rails-Aware'ではない(idという名前ではなく、コード設計上で一意とされている名称が使われる)

本来はRailsに合わせるべきなんだろうが、Railsのためだけにスキーマを修正してくれ、なんて、気むずかしいDBAに言おうものなら半××ものだろう。
従って、レガシ(あえてこう呼ぶ)なテーブルはRails側で流儀を合わせる必要がある。以下、その手順

これもいろいろな所で散々既出なので、詳しくは解説しない。備忘録としてメモ。(既にRailsコマンドでプロジェクトが生成されており、データベースにも接続可能になっていることとする)

どうせモデル名とテーブル名は合わないので、好きな名称でモデルクラスを生成する

script/generate model -f hoge
      exists  app/models/
      exists  test/unit/
      exists  test/fixtures/
      create  app/models/hoge.rb
      create  test/unit/hoge_test.rb
      create  test/fixtures/hoges.yml
      exists  db/migrate
      create  db/migrate/20090312053552_create_hoges.rb

このとき、マイグレーション用のスクリプト(*__create_hoges.rb)は使わないので放置していても良いが、偶々テーブル名が実際のスキーマに合致していると、マイグレーション実行時にテーブルを誤って変更したり消してしまったりする可能性も無いとは言えないので、心配な場合は修正しておくと良いだろう。ただし、その場合、最もおいしい機能であるマイグレーションによるスキーマの世代管理は諦めなくてはならない。

  • 2.テーブル名とプライマリキー名をオーバライドする

件の'Rails-Aware'ではない、テーブル名とプライマリキー名を生成されたモデルクラス(ActiveRecord::Baseクラスのサブクラス)で設定する。

# デフォルトのテーブル名とプライマリキーを変更する
class Hoge < ActiveRecord::Base
  set_table_name 'hogetable'
  set_primary_key 'hogepkey'
end

なお、テーブル名とプライマリキー名がはっきりと解っている場合は良いが、そうでは無い場合、一度スキーマのダンプを実行して、対象となるテーブルの情報をスクリプトとして入手しておくと、後々作業が楽だ。

#development属性でスキーマのダンプを実行する
rake environment -v -t RAILS_ENV=development db:schema:dump

このコマンドでdb/schema.rbが生成されるので、対象のテーブル属性を確認できる。
schema.rb

  create_table "hogetable", :primary_key => "hogepkey", :force => true do |t|
    t.string "hogemessage"
    t.string "hogedate", :limit => 14
  end

個人的にはこの記述を1.で生成したマイグレーション用のスクリプトに転記しておくことをお勧めする。(dropは自己責任で)

  • 3.コントローラを生成してモデルを使う

実質、作業は2までで終了。2.スキーマをダンプしていればカラム名も解っていると思うので、そのままActiveRecordで参照できるが、データを新たに生成する場合だけは注意する必要がある。というのも、プライマリキーに使用する列名は変更したが、ActiveRecord内では相変わらずプライマリキーに使用する属性の名前は'id'なので、新規にデータを保存する場合は適宜'id'という属性にプライマリキーフィールドの値をセットする必要がある。