テクノロジー
2018年1月9日Railsにおけるマイグレーションとは
今回はマイグレーションという仕組みについてです。
データのやりとりにおいてとても重要なポイントですので、ぜひ実際に手を動かしながら学んでいきましょう。
目次
マイグレーション
マイグレーションとは
マイグレーションで実現できること
マイグレーションファイルの作成
マイグレーションの実行
マイグレーションの実行順序
schema.rb
マイグレーションは一方通行
なぜこのような仕組みなのか
マイグレーションをやり直す方法
カラム追加用のマイグレーションファイルを新しく作成
rake db:rollback
rake db:migrate:reset
マイグレーション
今回はマイグレーションという仕組みについてです。
データのやりとりにおいてとても重要なポイントですので、ぜひ実際に手を動かしながら学んでいきましょう。
マイグレーションとは
テーブルを操作するには、SQL
を実行する必要があります。
しかしRailsでは マイグレーション
という仕組みのおかげで、 Ruby
でテーブル操作を行うことが可能です。
マイグレーションとは マイグレーションファイル
を元に テーブル操作
を行う仕組みです。
マイグレーションファイルとは、Rubyで書かれた テーブルの設計図
のことです。
テーブルの設計図とは カラム
や データ型
の定義が書かれた状態のことを指します。
マイグレーションで実現できること
ここで勘違いしないで頂きたいのは マイグレーションはテーブルを作成する機能だけではない
ということです。
マイグレーションは主に以下のことが実現できます。
- テーブル作成
- テーブル削除
- カラム追加
- カラム名変更
- カラムのデータ型変更
- カラム削除
先ほどマイグレーションの定義として テーブルに関する操作
と述べたのは、このような理由からです。
マイグレーションファイルの作成
マイグレーションファイルは モデルを作成した時
に一緒に作成されます。
さらに マイグレーションファイル単体
で作成することも可能です。
実際に rails g scaffold
というコマンドを使ってモデルを作成してみます。
- やってみましょう!
rails g scaffold Blog title:string content:text
マイグレーションファイルは db/migrate
ディレクトリに存在しています。
rails g scaffold
を実行した時にすでに作成されているので見てみましょう。
- やってみましょう!
(db/migrate/YYYYMMDDhhmmss_create_blogs.rb
)
class CreateBlogs < ActiveRecord::Migration
def change
create_table :blogs do |t| #=> この引数名(:blogs)がテーブル名になる
t.string :title
t.text :content
t.timestamps #=> この一行でcreated_atとupdated_atのカラムが定義される
end
end
end
次に中身がどうなっているかを見てみましょう。
create_table :blogs
という記述は、これからblogsという名前でテーブルを作りますという宣言を意味します。
do-end
の中にはカラムを定義してきます。
この場合、 t.string :title
と t.text :content
は string型のtitleという名前のカラム
と text型のcontentという名前のカラム
という意味になります。
さらに t.timestamps
は少し特殊で、この記述だけで レコードが作られた時間
を表す created_atカラム
と レコードが更新された時間
を表す updated_atカラム
を作成してくれます。
両者は datetime
というデータ型で定義されます。
さらにここには何も書かれていませんが、主キーである id
という名前のカラムも自動で作成してくれます。
マイグレーションの実行
マイグレーションを実行するときは以下のようにコンソールに実行します。
- やってみましょう!
(コンソール
)
$ rake db:migrate
マイグレーションの実行順序
マイグレーションの一番重要なポイントは 実行順序
です。
マイグレーションファイルは 時系列
で管理されています。
そのためマイグレーションファイルのファイル名は先頭が YYYYMMDDhhmmss
となっているはずです。
schema.rb
マイグレーションを実行すると schema.rb
というファイルが自動で更新されます。
(db/scema.rb
)
ActiveRecord::Schema.define(version: 20170302081241) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "blogs", force: :cascade do |t|
t.string "title"
t.text "content"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end
1行目の version: 20170302081241
のところに、実行が済んでいる最新マイグレーションファイルの日時が挿入されます。
そうすることで、マイグレーションがどこまで実行されたかが分かります。
ちなみに schema.rb
というファイルは自動で更新されるものなので 見る専門
だと認識しておいてください。
編集するとどうなるかは、興味のある方はやってみると良いと思います。
マイグレーションは一方通行
マイグレーションの実行は 一方通行
です。
そのため一度マイグレーションを実行したら、基本的には実行済みのマイグレーションファイルを書き換えても変更されません。
なぜこのような仕組みなのか
なぜマイグレーションは時系列で管理したり、一方通行にしたりしているのでしょうか?
これは チーム開発
が関係してきます。
例えば5人でチーム開発しているときに、5人が同時にテーブル操作を行ったらDB内が混乱してしまいます。
そのため時系列で、しかも 秒単位
で管理することで DB内を混乱させない
ようにしているのです。
マイグレーションをやり直す方法
テーブル操作を誤ったとき対応策は大きく3種類あります。
ここではblogsテーブルに status
というカラムを新たに追加する、という設定で話を進めていきます。
-
どちらか片方やってみましょう!
- カラム追加用のマイグレーションファイルを新しく作成
-
rake db:rollback
-
やらなくて良いです
- rake db:migrate:reset
カラム追加用のマイグレーションファイルを新しく作成
まず1つ目はマイグレーションファイルを新たに作成する方法です。
一方通行というマイグレーションの仕組みを逆手に取った方法と言えるでしょう。
以下のコマンドで新しくマイグレーションファイルが作成されます。
(コンソール
)
$ rails g migration add_column_to_blogs
その後マイグレーションファイルに以下を記述し、マイグレーションを実行します。
(db/migrate/YYYYMMDDhhmmss_add_column_to_blogs.rb
)
class AddColumnToBlogs < ActiveRecord::Migration
def change
add_column :blogs, :status, :integer
end
end
この場合 :blogs
は blogsテーブル
、 :status
は statusカラム
、 :integer
は integerというデータ型
を意味します。
(コンソール
)
$ rake db:migarte
rake db:rollback
rake db:rollback
コマンドは、マイグレーションの実行を指定した数だけ戻してくれるコマンドです。
逆に言えば指定した数だけ、マイグレーションがリセットされるということです。
例えば以下のようなケースで、マイグレーションを1つだけ戻したいとします。
するとschemaの日時が変更され、マイグレーションが1つ戻ります。
(コンソール
)
$ rake db:rollback STEP=1
この場合 db/migrate/YYYYMMDDhhmmss_create_blogs
のマイグレーションがリセットされます。
(db/migrate/YYYYMMDDhhmmss_create_blogs.rb
)
class CreateBlogs < ActiveRecord::Migration
def change
create_table :blogs do |t|
t.string :title
t.text :content
t.integer :status # 追記
t.timestamps
end
end
end
その後上記のように db/migrate/YYYYMMDDhhmmss_create_blogs
を編集し、マイグレーションを実行します。
(コンソール
)
$ rake db:migrate
rake db:migrate:reset
rake db:migrate:reset
コマンドは、DBから全てリセットしてマイグレーションを1から実行するコマンドです。
まずは以下のようにマイグレーションファイルを編集します。
- やらなくて良いです
(db/migrate/YYYYMMDDhhmmss_create_blogs.rb
)
class CreateBlogs < ActiveRecord::Migration
def change
create_table :blogs do |t|
t.string :title
t.text :content
t.integer :status # 追記
t.timestamps
end
end
end
次に以下のコマンドを実行します。
- やらなくて良いです
(コンソール
)
$ rake db:migrate:reset
先ほど述べたように DBから全てリセット
するので、顧客のデータや個人情報を抱えた状態でこのコマンドを実行したら大変なことになるのは分かりますね。
なので使うときには気をつけなければなりません。
いかがでしたでしょうか。マイグレーションを理解することはRailsでの開発だけでなく、チーム開発にとって非常に重要なポイントになります。不明点があれば、ぜひ繰り返し学習をして身につけていきましょう。