Rails Migration(マイグレーション)入門。マイグレーションのメリットと使い方
今回はマイグレーションについて説明していきます。マイグレーションはアプリケーションのテーブル定義を変更するためのツールです。
素朴にテーブル定義を変更しようとするとSQLを書く形になりますが、テーブルの作成やカラムの追加というのは重複して書かないといけないことがあったりして非効率なので、Railsではマイグレーションでより簡単にスキーマ定義を変更することができるようになっています。
マイグレーションを使うメリット
冒頭でマイグレーションを使うとテーブル定義の変更が容易になるということを説明しましたが、マイグレーションには他のメリットもあります。
- 定義変更ためのコードが少なくてすむ(SQLを書く必要がない)。
- テーブルの変更をソースとして管理できる。
- SQLを書かないのでデータベースの種類に依存せずにすむ。
定義変更ためのコードが少なくてすむ
これは冒頭の説明と重複する部分もあるのですが、Railsでマイグレーションを使用するとテーブルを変更するためのジェネレータが使えるのでいちいちSQLを書く必要がなくなります。SQLでテーブル定義をおこなっていくと、テーブルを作成するためのSQLもカラムを追加するためのSQLもどうしても同じ様なSQLになっていきます。マイグレーションを使うとこういった無駄な作業を省略できるのでこの記事を読んでいるかたには是非とも進んで身につけてほしいと思います。
マイグレーションは次のようにコンソールからコマンドを叩くことで生成できます。
$ rails g migration CreateBlog title:string content:text status:integer
Running via Spring preloader in process 19076
invoke active_record
create db/migrate/20181007031625_create_blog.rb
上のコマンドで生成されたファイルがこちらです。
db/migrate/20181007031625createblog.rb
class CreateBlog < ActiveRecord::Migration[5.1]
def change
create_table :blogs do |t|
t.string :title
t.text :content
t.integer :status
end
end
end
ファイルが生成されたらあとはこのファイルを実行するだけでテーブルが作成できてしまいます。
rails db:migrate
SQLを書いたことがある方はわると思いますが、テーブル変更の手軽さが断然違います。
テーブルの変更をソースとして管理できる
さきほど実際にマイグレーションファイルを作成しましたが、テーブルを変更する際は常にマイグレーションを使うようにするとテーブルの変更の履歴をソースでのこしておくことができます。
Railsの場合マイグレーションで作成したコードはdb/migrate配下に出力されるので、そのまま生成さらたコードをgitにコミットしてしまえば、どういう順番でどのような変更が加わったかということを保存しておくことができます。
これをしておくとデグレが起きた時の調査も容易ですし、チームで開発した際にあらたにどのようにテーブルが変更されたのかというもうわかりやすくなります。
SQLを書かないのでデータベースの種類に依存しないですむ
今回散々SQLを書かなくてすむということを言っていますが、これのメリットは記述量がすくなくてすむということもそうですが、マイグレーションを使うことによって使用しているデータベースがMySQLなのかSQLiteなのかPostgresSQLなのかというのを意識しないですむということでもあります。
データベースの種類の違いはActiveRecordがうまく吸収するということができるので、開発がすすんでDBを変更したいという場合にソースは変更せずにデータベースだけ変更するというようなことができるようになります。
マイグレーションの使い方
先にマイグレーションを生成から実行までの流れは説明してみせましたがこちらでは、より詳しくマイグレーションの流れを説明していきます。
マイグレーションコードの生成
まずはマイグレーションコードの生成についてです。先ほどの例ではテーブルを作成するのに直接マイグレーションコードを生成しましたが、実際の開発ではテーブルと合わせてモデルも一緒に作成した方が良いのでモデルをジェネレートする形が望ましいです。
$ rails g model category name:string description:text order:integer
Running via Spring preloader in process 41449
invoke active_record
create db/migrate/20181007040322_create_categories.rb
create app/models/category.rb
invoke rspec
create spec/models/category_spec.rb
invoke factory_bot
create spec/factories/categories.rb
このようにとくにオプションを指定しなければモデルを生成することでマイグレーションコードも作成できます。
class CreateCategories < ActiveRecord::Migration[5.1]
def change
create_table :categories do |t|
t.string :name
t.text :description
t.integer :order
t.timestamps
end
end
end
model/migrationを生成する時の基本のコマンドの形は以下です。
rails g model [モデル名(単数形)] [カラム1:型1] [カラム2:型2]...
rails g migration [マイグレーション名] [カラム1:型1] [カラム2:型2]...
モデルを生成する場合のモデル名はRailsの規約にそって先頭大文字の単数形の名前をつけるようにしてください。 さきほどから説明なしにrails gというコマンドを多用していいますが、gはgenerationの略でrails generation model ..のようにしても問題なく動きます。
マイグレーションコードの内容
先ほど作成したマイグレーションコードはこちらですが、内容を説明していくと、CreateCategoriesというクラスのなかにchangeメソッドというメソッドが一つあり、そのなかでcreatetableというメソッドを実行しています。 実際に作成するテーブル名は、createtableの第一引数に与えて、実際のテーブル定義はそのあとのブロックの中に記述していきます。
class CreateCategories < ActiveRecord::Migration[5.1]
def change
create_table :categories do |t|
t.string :name
t.text :description
t.integer :order
t.timestamps
end
end
end
カラム定義は
t.[型] [カラム名], [オプション]
という形で行なっていきます。オプションにはkeyとvalueの形でオプションを渡すことができ、nullを許容しないカラムを作成したい場合は
t.string :name, null: false
のような形で記述していきます。
テーブル定義の最後にt.timestampsというものがありますがこれを宣言しておくとテーブルにcreatedatとupdatedatというレコードの作成時間と更新時間を記録するカラムが作成されます。とくに理由がない場合は常に宣言しておく形がのぞましいです。
マイグレーションの実行
マイグレーションの実行はさきにもあったように
rails db:migrate
で実行できます。railsはschema_migrationsというテーブルですでに実行済みのマイグレーションかどうかを判断して差分で実行するので、db/migration配下にファイルがいくつかあっても今回新規で追加されたマイグレーションファイルだけ実行してくれます。
ほかにも全てのマイグレーションをリセットして最初からやり直したい場合は
rails db:migrate:reset
というコマンドもあります。
まとめ
以上、今回はマイグレーションを使用するメリットとその使い方について説明しました。マイグレーションを使い始めると生のSQLを書くのが苦痛になるほど便利なのでRailsをつかっているのであれば積極的につかってください。
またメリットにも書いたようにマイグレーションを使うことで変更の履歴を残せたりテーブルの変更が自動化できるので、本番へのデプロイの自動化やデグレが発生した場合の調査などが非常にやりやすくなります。マイグレーションを使うに当たってはこういったメリットもしっかり理解しながら使っていただけるとよいのかなと思います。
今回は概論的な要素がつよかったですが、他の記事でカラムを追加・削除・変更するときはどうやって書くの?という部分やマイグレーションタスクの種類について詳しく説明していきたいと思います。