LoginSignup
1
0

More than 5 years have passed since last update.

マイグレーションのreferenceの挙動まとめ

Last updated at Posted at 2018-04-09

 目的

railsのマイグレーションで外部キーを作成する時に、referenceをよく使うけど、「あれ、foreign_key: true必要なんだっけ?」 「indexって勝手につくんだっけ?」 っていつもなるから、まとめておく。

前提

  • mysql5.7.18 (DBが違うと挙動が違うことがあるので注意)
  • rails5.1.6

まず試す

テーブルの作成から

rails g model test_model test_column:references

とすると、以下のファイルが生成される。

db/~~~create_test_models.rb
class CreateTestModels < ActiveRecord::Migration[5.1]
  def change
    create_table :test_models do |t|
      t.references :test_column, foreign_key: true

      t.timestamps
    end
  end
end

bundle exec rake db:migrate で、、

db/schema.rb
ActiveRecord::Schema.define(version: 20180409130332) do
  ...
  create_table "test_models", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.bigint "test_column_id", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["test_column_id"], name: "index_test_models_on_test_column_id"
  end
  ...
  add_foreign_key "test_models", "test_columns"
  ...
end

references使ったらindexは自動でつきますね、、
foreign_keyは指定してあげないとつかないみたい。

一応foreign_key: trueがない場合でもやってみよう。

db/~~~create_test_models.rb
class CreateTestModels < ActiveRecord::Migration[5.1]
  def change
    create_table :test_models do |t|
      t.references :test_column, null: false

      t.timestamps
    end
  end
end

bundle exec rake db:migrate で、、

db/schema.rb
ActiveRecord::Schema.define(version: 20180409130332) do
  ...
  create_table "test_models", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.bigint "test_column_id", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["test_column_id"], name: "index_test_models_on_test_column_id"
  end
  ...
end

やはりforeign key制約はついてない。

add_referenceもやってみよう。

rails g migration AddAdditionalColumnToTestModels additional:references

db/~~~add_additional_column_to_test_models.rb
class AddAdditionalColumnToTestModels < ActiveRecord::Migration[5.1]
  def change
    add_reference :test_models, :additional, foreign_key: true
  end
end

同じ感じ。 foreing_key: true がついているので、

db/schema.rb
ActiveRecord::Schema.define(version: 20180409130332) do
  ...
  create_table "test_models", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
    t.bigint "test_column_id", null: false
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.bigint "additional_id"
    t.index ["additional_id"], name: "index_test_models_on_additional_id"
    t.index ["test_column_id"], name: "index_test_models_on_test_column_id"
  end
  ...
  add_foreign_key "test_models", "additionals"
  ...
end

indexforeign keyもついてる。

結論

t.reference自体はindexは貼ってくれるが、foreign_key制約までは面倒をみてくれない。だから、自分で書くときはforeign_key: trueを忘れずに。

1
0
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
1
0