Ruby on RailsでDBのバージョン管理覚え書き

※Rails2.0.xでの方法ですので、ご注意を。 詳しくはスクリーンキャストを見てね。


Railsの開発ではdb/migrate/nnn_xxxxxxxxxxx.rb というファイルにDBへの変更履歴が保存しますが、このファイルへの保存は「直接db/migrate/nnn_xxxxxxxxxxx.rbという名前のファイルを作成して、変更して」というやり方ではなく、基本的にrakeコマンドを実行してあげます。
db/migrate/nnn_xxxxxxxxxxx.rbのファイルにはDBの定義情報や変更情報を記述するのですが、このファイルから実際にDBへ反映する際もrakeコマンドを用いて移行します。
さらに、db/migrate/nnn_xxxxxxxxxxx.rbファイルをsubversionなどで管理しておくことで、他のメンバーと「DBの変更」をファイルとして共有でき、かつ他のメンバーもrakeコマンド一発で好きなバージョンのDBにすることができるという仕組みです。 →これ考えた人頭いいね!

まず

$ rails プロジェクト名

でプロジェクトを作成した直後に、database.ymlを自分の環境に合わせて修正します。(ちゃんと接続できてDBの作成権限を付けてあげてね!)

次に

$ cd プロジェクト名
$ rake db:create

で空っぽのDBを作成します

んで、適当にmodelを作成してみます。ここではスクリーンキャストに習ってtaskモデルです。

$ ruby script/generate model task name:string priority:integer

すると、db/migrate/001_create_tasks.rb とうファイルが作成されます。

[db/migrate/001_create_tasks.rb]

class CreateTasks < ActiveRecord::Migration
  def self.up
    create_table :tasks do |t|
      t.string :name
      t.integer :priority

      t.timestamps
    end
  end

  def self.down
    drop_table :users
  end
end

ソースを見てみると何となく分かると思いますが、これがテーブルの作成スクリプトになります。しかもSQLじゃないです。 self.upの部分がバージョンを上げる時のスクリプト、self.downの部分がバージョンを下げる時のスクリプトです。 なお、このスクリプトが作成された直後は、直接このファイルをいじっても問題ありませんが、他の人が別のテーブルを追加したりしてくると、非常にややこしくなるので最初以外は触らない方が賢明です。

[db/migrate/001_create_tasks.rb]

class CreateTasks < ActiveRecord::Migration
  def self.up
    create_table :tasks do |t|
      t.string :name
      t.integer :priority, :position # ← 最初は直接編集して列を追加してもOK
      t.timestamps
    end
  end

  def self.down
    drop_table :users
  end
end

このスクリプトだけで、id, name, priority, :position, created_at, updated_at の5カラムのテーブルが作成されます。 では、実際にDBに反映する時はどうするかと言いますと、

$ rake db:migrate

とやってあげるだけです。 これでDBにテーブルが作成されました。

もう一つテーブルを作成しておきましょう。 非常に簡単な例ですいません(^ ^;;)

$ ruby script/generate project name:string

すると、db/migrate/002_create_projects.rb とうファイルが作成されます。

[db/migrate/002_create_projects.rb]

class CreateProjects < ActiveRecord::Migration
  def self.up
    create_table :projects do |t|
      t.string :name

      t.timestamps
    end
  end

  def self.down
    drop_table :users
  end
end

んで、このテーブルも反映させておきましょう。

$ rake db:migrate

と、ここまで順調にやってきたのですが、あなたはここで気がつくでしょう。
 「あ、タスクテーブルに期限の項目いれるの忘れてたテヘヘ(* ̄ー ̄)>」
そんな時でもrailsならば大丈夫。 コマンドラインから

$ ruby script/migration add_deadline_to_task deadline:date

と打ってあげると、db/migrate/003_add_deadline_to_task.rb というカッコいいファイル名のスクリプトを作成してくれます。

[db/migrate/003_add_deadline_to_task.rb]

class AddDeadlineToTask < ActiveRecord::Migration
  def self.up
    add_column :tasks, :deadline, :date
  end

  def self.down
    remove_column :tasks, :deadline
  end
end

このスクリプトがテーブルに列を追加してくれます。 ちなみに、逆にテーブルから列を削除する場合は・・・

$ ruby script/migration remove_deadline_from_task deadline:date

という風にコマンドラインから打ち込みます。 「add_列名_to_テーブル名」が列の追加、「remove_列名_from_テーブル名]が列の削除。 この書式で書くと自動的に該当の処理をしてくれるスクリプトを作成してくれます。


これで最新バージョンのDB定義に移行するには、

$ rake db:migrate

とやってあげればOKです。 逆に前のバージョン(ここでは列の追加前)に戻したい時は、

$ rake db:migrate VERSION=2

とやってあげれば、002_create_projects.rb まで実行された状態のDBになってくれます。


ここで耳より情報。
テーブル作成のスクリプトにどうしても手を加えたい場合は、手を加えた後に、

$ rake db:migrate VERSION=0
$ rake db:migrate

とやってあげると、一度きれいさっぱり全てのテーブルを削除した後に、全テーブルを造り直してくれます。


な〜んていいながら、僕は全部Aptanaまかせです〜