Railsでmigrationする時の小技


# Rails5.1以降のテーブルとRails5.0以前のテーブルを関連付ける方法
Rails5.0以前はPKのデフォルトがintegerだったけどRails5.1からはbigintに変更されてる。
その影響でRails5.0以前に作成したテーブルへRails5.1以降のテーブルからFKを貼ろうとすると型が違うので怒られる。

参考になった記事：[Rails 5.1以前に作成されたテーブルにFK制約を張れない問題の解決策](https://qiita.com/nametaketakewo/items/d9d26fb301a09d7e6c2c)

下記は怒られたケースのサンプル

```ruby
# 前提：user_groupsテーブルがrails5.0以前に作成されておりidはintegerとする。
class CreateUsers < ActiveRecord::Migration[5.1]
  def change
    create_table :users do |t|
      t.references :user_group, 	null: false, index: true, comment: 'user_groups.id'
      t.string     :name,        null: false, comment: '氏名'
      t.string     :furigana,	 null: false, comment: 'ふりがな'

      t.timestamps null: false
    end
  end
end
```

## 解決方法
参考リンクに書いてある通りなんだけど2通りの解決方法が考えられる。

* 5.1以降のテーブルのFKの型をintegerに変更する。
* 5.0以前に作成されたテーブルのPKの型をbigintに変更する。

状況によるけどrails5.0以前のテーブルは稼働中の状況が多そうなので`FKの型をintegerに指定する方法`のほうが影響範囲が小さくなる傾向にある気がする。(システム刷新みたいな時には`PKの型を変更する方法`を選択するのかな)

FKの型をintegerに変更する方法にも2種類あるけど`references`を使ってtypeオプションで指定する方法がスッキリしてて個人的には好み。(下にtypeオプションを追加したサンプルを書いておく)
もう１種類はinteger型に指定してカラムを作った後、`add_foreign_key`でFKを別途作成する方法。

```ruby
class CreateUsers < ActiveRecord::Migration[5.1]
  def change
    create_table :users do |t|
      # FK作成時の型をtypeオプションを使ってinteger型に指定する
      t.references :user_group, 	null: false, index: true, comment: 'user_groups.id', type: integer
      t.string     :name,        null: false, comment: '氏名'
      t.string     :furigana,	 null: false, comment: 'ふりがな'

      t.timestamps null: false
    end
  end
end
```


# DROPする際にrollback用の処理をスッキリ書く
テーブルを使う必要がなくなって削除する際にrollback出来るようにしておこうってときがある。
そんな時にシュッと書くためのtips。要はrequireして実行させる。

```ruby
# 20170101132451_create_users.rb
# テーブル作成時のマイグレーションファイル
class CreateUsers < ActiveRecord::Migration[5.1]
  def change
    create_table :users do |t|
      t.references :user_group, 	null: false, index: true, comment: 'user_groups.id'
      t.string     :name,        null: false, comment: '氏名'
      t.string     :furigana,	 null: false, comment: 'ふりがな'

      t.timestamps null: false
    end
  end
end
```


## 悪い書き方
create時の内容をコピペ。typoの可能性もある。

```ruby
# 20180101090509_drop_users.rb 
# テーブル削除時のマイグレーションファイル
class DropUsers < ActiveRecord::Migration[5.1]
  def up
    drop_table :users, if_exists: true
  end

  def down
    create_table :users do |t|
      t.references :user_group, 	null: false, index: true, comment: 'user_groups.id'
      t.string     :name,        null: false, comment: '氏名'
      t.string     :furigana,	 null: false, comment: 'ふりがな'

      t.timestamps null: false
    end
  end
end
```

## 良い書き方
create時のファイルをrequireして実行。typoの可能性はないしシンプル。

```ruby
# 20180101090509_drop_users.rb
# テーブル削除時のマイグレーションファイル
require './db/migrate/20170101132451_create_users.rb'

class DropUsers < ActiveRecord::Migration[5.1]
  def up
    drop_table :users, if_exists: true
  end

  def down
    CreateUsers.new.change
  end
end
```

# カラムを追加する際に挿入箇所を指定する方法
テーブルへカラムを追加する時、何も考えずに`add_column`すると最後のカラムの後ろに追加される。
関連する順番にカラムが並んでいると理解しやすいがバラバラだと判りにくい。。。

## 解決方法
`add_column`に`after`オプションを追加すれば良い。
※DBがMySQLの場合に有効だけどPostgreSQLの場合は無効

``` ruby
# nameカラムの後ろにkanaカラムを追加する。
def change
	add_column :users, :kana, :string, null: false, after: :name, comment: '名前のフリガナ' 
end
```