LoginSignup
3
1

More than 5 years have passed since last update.

Railsでmigrationする時の小技

Last updated at Posted at 2018-02-12

Rails5.1以降のテーブルとRails5.0以前のテーブルを関連付ける方法

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

参考になった記事:Rails 5.1以前に作成されたテーブルにFK制約を張れない問題の解決策

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

# 前提: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オプションを追加したサンプルを書いておく)
もう1種類はinteger型に指定してカラムを作った後、add_foreign_keyでFKを別途作成する方法。

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して実行させる。

# 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の可能性もある。

# 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の可能性はないしシンプル。

# 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_columnafterオプションを追加すれば良い。
※DBがMySQLの場合に有効だけどPostgreSQLの場合は無効

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1