Ruby on Rails : migration 機能リファレンス
本日は Ruby on Rails の migration 機能の続きです。前回の記事では migration 機能の基本的な使用方法をご紹介しました。本日はリファレンス編ということで、migration で使用されるメソッドをご紹介しようと思います。合わせて、migration を記述する上で知っていると便利な Tips もいくつか記載しましたので、ぜひ参考にしてくださいね(^^)
スキーマ変更を行うメソッド
まずはスキーマを変更するためのデータベース操作をラップしたメソッドをご紹介します。前回の記事で使用した create_table 以外にもたくさんのメソッドが用意されています。これだけあれば、ほとんどの操作は SQL を書かずに実現できることでしょう。
なお、これらのメソッドではテーブル名やカラム名を引数として指定するようになっていますが、それらはシンボルで指定してください。具体的には、以下のように名前の前に ":"(コロン )を付けます。
add_column(:table_name, :column_name, ...)
おそらく高速化のためにシンボルを使用しているものと思います。処理内容にもよりますが、Ruby では文字列よりもシンボルのほうが効率よく処理が行えるようです。 Ruby on Rails では随所でシンボルが活用されていますので、早めに慣れてしまいましょう。
では、それぞれのメソッドをご紹介します。
create_table(name, option)
テーブルを作成します。引数の意味は次のとおりです。
- name
- 作成するテーブルの名前。
- option
- 以下の任意の要素を含むハッシュ。
キー | 値 |
---|---|
:id | false なら id カラムを自動作成しない |
:primary_key | 主キーのカラム名 |
:options | SQL の最後に付加する文字列 |
:temporary | 一時的なテーブルを作成 |
:force | true なら古いテーブルを削除するしてから作成 |
また、ブロックを指定することでテーブルに含むカラムを指定することができます。ブロック引数には TableDefinition クラスのインスタンスが渡され、主にその column メソッドでカラムを定義します。column メソッドの引数は後述の add_column メソッドから第 1 引数(テーブル名)を抜いたものです。具体的な使用例は前回の記事をご参照ください。
なお、バックエンドデータベースとして MySQL を使用している場合、:options を指定しないと "ENGINE=InnoDB" がデフォルトで指定されます。
drop_table(name)
指定されたテーブルを削除します。引数の意味は以下のとおりです。
- name
- 削除するテーブルの名前。
rename_table(old_name, new_name)
指定されたテーブルの名前を変更します。引数の意味は以下のとおりです。
- old_name
- 変更前のテーブルの名前。
- new_name
- 変更後のテーブルの名前。
add_column(table_name, column_name, type, options)
カラムを追加します。引数の意味は以下のとおりです。
- table_name
- カラムを追加するテーブルの名前。
- column_name
- 追加するカラムの名前。
- type
- データ型の指定。":primary_key", ":string", ":text", ":integer", ":float", ":decimal", ":datetime", ":timestamp", ":time", ":date", ":binary", ":boolean" のうちのいずれか。
- options
- 以下の任意の要素を含むハッシュ。
キー | 値 |
---|---|
:limit | 文字列などのデータ長 |
:default | カラムのデフォルト値。省略すると NULL になる |
:null | false なら NULL を禁止する |
:precision | :decimal 型の精度を指定する |
:scale | :decimal 型の小数点以下の桁数 |
rename_column(table_name, column_name, new_column_name)
指定されたカラムの名前を変更します。引数の意味は以下のとおりです。
- table_name
- 名前変更するカラムが存在するテーブルの名前。
- column_name
- 変更前のカラムの名前。
- new_column_name
- 変更後のカラムの名前。
change_column(table_name, column_name, type, options)
指定されたカラムの属性を変更します。引数の意味は以下のとおりです。
- table_name
- 属性を変更するカラムが存在するテーブルの名前。
- column_name
- 属性を変更するカラムの名前。
- type
- 新しいデータ型。指定できる値は add_column と同じ。
- options
- 新しいオプション。指定できる値は add_column と同じ。
change_column_default(table_name, column_name, default)
指定されたカラムのデフォルト値を変更します。このメソッドではデフォルト値を NULL に変更することはできないようです。引数の意味は以下のとおりです。
- table_name
- デフォルト値を変更するカラムが存在するテーブルの名前。
- column_name
- デフォルト値を変更するカラムの名前。
- default
- 新しいデフォルト値。
remove_column(table_name, column_name)
指定されたカラムを削除します。引数の意味は以下のとおりです。
- table_name
- 削除するカラムが存在するテーブルの名前。
- column_name
- 削除するカラムの名前。
add_index(table_name, column_name, options)
検索用のインデックスを追加します。インデックスの名前はデフォルトで "<テーブル名>_<最初のカラム名>_index" になりますが、options に :name を指定することで任意の名前を指定できます。引数の意味は以下のとおりです。
- table_name
- インデックスを作成するテーブルの名前。
- column_name
- 対象カラムの名前。複数のカラムを対称にする場合はシンボル配列で指定する。
- options
- 以下の任意の要素を含むハッシュ。
キー | 値 |
---|---|
:name | インデックスの名前。 |
:unique | true を指定すると UNIQUE なインデックスになる。 |
remove_index(table_name, options)
検索用のインデックスを削除します。このメソッドには主に 2 つの呼び出し方があります。最初は削除するインデックスをカラム名で指定する形式で、以下の書式になります。
remove_index(<テーブル名>, :column => <カラム名>)
この形式では、add_index メソッドと同じ方法でインデックス名を作成し、そのインデックスを削除します。複数カラムを対象としたインデックスでも、最初のカラムを指定するだけで削除できることに注意してください。第 2 の形式はインデックス名を直接指定する方法です。
remove_index(<テーブル名>, :name => <インデックス名>)
この形式なら任意の名前のインデックスを削除できます。add_index で名前を指定してインデックスを作成した場合に使用します。
execute(sql)
指定された SQL 文を実行します。このメソッドを使えば SQL で記述可能なすべての処理が行えます。ただし、データベースエンジンに依存してしまう可能性が高いので、特定の環境への依存を避けたい場合は使わないほうが無難かもしれません。引数の意味は以下のとおりです。
- sql
- 実行する SQL 文。
以上、これだけ知っていればほぼ自在に migration が記述できると思います。 SQL は必要以上に複雑な面があるので、それを使わなくていいというのは助かりますね(^^;
Tips
おまけとして、migration を記述する際に知っておくと便利な Tips をご紹介します。無用なトラブルを避けるためにも、目を通していただけるとよいと思いますよ。
ロールバック不可能な変更を行う場合
migration の up メソッドで完全なロールバックが不可能な変更を行う場合(テーブルの削除など?)、down メソッドでは IrreversibleMigration 例外を投げることが推奨されています。以下のような感じでしょうか。
class RemoveFoo < ActiveRecord::Migration def self.up drop_table(:foo) end def self.down raise IrreversibleMigration end end
ただし強制ではないので、重要性が低いと判断すれば例外を投げなくてもよいと思います。
Migration 中のデータ操作
migration の up, down のメソッド中では前述のスキーマ変更メソッドだけではなく、モデルクラスを使用したデータ操作も可能です。以下の例では、前回の記事で作成したカテゴリーテーブルから名前が空文字列になっているカテゴリーを削除しています。
class RemoveEmptyCategories < ActiveRecord::Migration def self.up Category.find(:all).each do |category| category.destroy if category.name.empty? end end end
スキーマ変更後のデータ操作
前述のスキーマ変更メソッドでデータベースのスキーマを変更した後にモデルクラスによるデータ操作を行う場合は、モデルクラスの reset_column_information メソッドを呼んでカラムの情報をリセットする必要があります。
class AddUniqueNumber < ActiveRecord::Migration def self.up add_column(:categories, :number, :integer) Category.reset_column_information num = 0 Category.find(:all).each do |category| category.number = num num += 1 end end def self.down remove_column(:categories, :number) end end
テーブルを UTF-8 対応にする
日本語を扱う場合、テーブルの文字コードを UTF-8 にしておかないと文字化けしてしまう可能性があります。データベース作成時にデフォルトとして UTF-8 を指定しておくのが理想ですが、場合によってはそれが不可能なこともあるでしょう。そういう場合は、create_table メソッドの :options を利用します。前回の記事 と同じ例ですが、以下のような感じです。
class AddCategoryTable < ActiveRecord::migration def self.up create_table(:categories, :options => "ENGINE=InnoDB DEFAULT CHARACTER SET=UTF8") do |t| t.column(:name, :string, :limit => 200, :null => false) end end def self.down drop_table(:categories) end end
:options を明示的に指定するとデフォルトの "ENGINE=InnoDB" の指定が無効になるので、それも含めてやる必要があります。けっこう忘れがちなので注意してください。
本日は、migration で使用するメソッドをご紹介しました。migration は SQL よりも記述が簡単で、しかもバージョン管理も可能という優れものですから、利用しない手はありません。 Ruby on Rails を使う主なメリットのひとつに数えてしまっても遜色ないと思います。 Ruby on Rails を利用する際は、ぜひ活用してください!(^^)
詳しくはこちらの記事をどうぞ!
この記事にコメントする