[Rails]マイグレーションファイルについて勉強してみた！(テーブルへのカラム追加)

#はじめに
Railsを操作していると、何となく存在は知っているけど、それがどういう役割を果たしているのかよく分かっていないファイルやコマンドが数多くあることに気づきました。
その中の一つが、マイグレーションファイルです。

モデルを作ると、なぜか知らんがマイグレーションファイルが出来上がっていて、`rails db:migrate`を打ち込むと、``schema.rb``にテーブルデータとして反映する...
それぐらいの認識でしたが、そこについて深掘りして解説していきます！

#マイグレーションファイルとは
マイグレーションファイルは、データベースを生成する際の設計図になるものです。
また、マイグレーションファイルを実行することで、記述した内容に基づいたデータテーブルが生成されます。

#マイグレーションファイルを生成する
ターミナルに、以下のように打ち込み、モデルを作成すると、自動的にマイグレーションファイルも生成されます。

```ruby:基本構文
rails g model モデル名  #ここでは、モデル名を「book」とします
```

```ruby:db/migrate/20201114044025_create_books.rb
class CreateBooks < ActiveRecord::Migration[5.2]
  def change
    create_table :books do |t|
      t.timestamps
    end
  end
end
```

マイグレーションファイルが出来上がった初期状態では、``t.timestamps``のみがデフォルトで記載されていることが分かります。
それにより、作成日時を意味する``created_at``と、更新日時を意味する``updated_at``がカラムに追加されるのです。

それでは、早速作成したマイグレーションファイルを実行していきましょう！
実際に必要になってくるカラムが色々不足している気もしますが、ここはあえてこのままでいきます！

#マイグレーションファイルを実行する
作成したマイグレーションファイルは、ターミナルに下記のコマンドを打ち込むと読み込まれ、データベースに反映されます。

```ruby:コマンド
rails db:migrate
```

#マイグレーションファイルの状態を確認
今回は作成したマイグレーションファイルが一つだけでした。
中には、同時に何個ものモデルを作成することもあると思います(というか、そっちの方が多い気もします)。
そんな時に、自分が作成したマイグレーションファイルが、どこまで実行されているか確認したいときは、以下のコマンドをターミナルに打ち込みましょう。

```ruby:コマンド
rails db:migrate:status
```

そうすると、ターミナルに現在のマイグレーションファイルの状態が出力されます。

```ruby:ターミナル
Status   Migration ID    Migration Name
--------------------------------------------------
  up     20201114044025   Create books
```

> upになっているマイグレーションファイルはすでに実行済みのファイルなので``rails db:migrate``コマンドを入力しても読み込まれることはありません。
> なのでもし間違った名前でカラムを作成してしまったときに``up``になっているマイグレーションファイルを編集しても、読み込まれないので意味がないことになります。

参照：[【Rails】マイグレーションファイルを徹底解説！](https://pikawaka.com/rails/migration)

なるほど、それでは、今作成したばかりのbooksテーブルに、新たにカラムを追加したいときは、どうすればいいのでしょうか？
ひとまず、スキーマファイルを確認しにいきましょう！

#スキーマファイルとは
マイグレーションが実行されるとdbフォルダに``schema.rb``というファイルが作成されます。
早速中身をみましょう。

```ruby:db/schema.rb
ActiveRecord::Schema.define(version: 2020_11_14_044025) do
  create_table "books", force: :cascade do |t|
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end
end
```

無事にテーブルが作成されているようです。
``force: :cascade``という記述により、外部キーが適切であればスキーマが再読み込みできるようになります。
それでは、ここに``title``というカラムを追加しましょう！

#カラムを追加する方法
既存のテーブルに、カラムを追加する方法は2種類あります。

１. 新たにマイグレーションファイルを作成して、カラムを追加する
2. ``rails db:rollback``でカラムを追加する

##①カラムを追加するためのマイグレーションファイルを作成する
この場合は、ターミナルに以下のコマンドを入力します

```ruby:コマンド
rails g migration Add追加するカラム名To追加するテーブル名 追加するカラム名:型
```

今回の場合だと、以下のようになりますね。

```ruby:ターミナル
rails g migration AddTitleToBooks title:string
```

すると、以下のようなマイグレーションファイルが作成されます。

```ruby:マイグレーションファイル
class AddTitleToBooks < ActiveRecord::Migration[5.2]
  def change
    add_column :books, :title, :string
  end
end
```

あとは、マイグレーションファイルを実行すれば、``title``カラムがテーブルにめでたく追加されます。

```ruby:コマンド
rails db:migrate
```

##②``rails db:rollback``でカラムを追加する

```ruby:コマンド
rails db:migrate:rollback
```

ターミナルにこのコマンドを入力すると、最新のマイグレーションファイルのバージョンが``rails db:migrate``する前の状態に戻ります。
今回の場合で言うと、ターミナルの表示が以下のように変化します。

```ruby:ターミナル
Status   Migration ID    Migration Name
--------------------------------------------------
 down   20201114044025    Create books  #upからdownになっている！！！！
```

つまり、``up``から``down``になることで、データベースが``rails db:migrate``される前の状態に戻ります。
db:migrate前に戻ったので、最初に作成されたマイグレーションファイルに、``title``カラムを追記してあげることができます。

```ruby:db/migrate/20201114044025_create_books.rb
class CreateGenres < ActiveRecord::Migration[5.2]
  def change
    create_table :books do |t|
      t.string :title    #ここにtitleカラムを追加！！！！
      t.timestamps
    end
  end
end
```

あとは①のパターンと同様に、マイグレーションファイルを実行すれば、``title``カラムが追加されます。

```ruby:コマンド
rails db:migrate
```

```ruby:db/schema.rb
ActiveRecord::Schema.define(version: 2020_11_14_044025) do
  create_table "books", force: :cascade do |t|
    t.string "title"  #titleカラムが追加された！！！！
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end
end
```

#おわりに
マイグレーションファイルの修正を行う作業は、思っている以上にセンシティブになることが多いので、タイミングや順序などをしっかりと理解した上で取り組むべきだと再認識できました。
また一つ勉強になりました！！