Rails referensesと外部キー制約について - Hashimoto-Noriaki/rails-rspec-memo GitHub Wiki

最終更新日 2024年07月20日 投稿日 2021年07月24日

referencesとは

外部キー制約を作成するための手助けをする方法の一つです。

  • 参照カラムの追加 関連するテーブルのIDを参照するカラムが追加
  • インデックスの作成 参照カラムに対してインデックスが作成(DBの検索速度を上げるための仕組み)
  • 外部キー制約の設定 オプションで外部キー制約を追加

ex) articlesテーブルにuser_idというカラムを追加し、それがusersテーブルのidカラムを参照するようにしたい時

rails g migration AddUserRefToArticles user:references
class AddUserRefToArticles < ActiveRecord::Migration[6.0]
  def change
    add_reference :articles, :user, null: false, foreign_key: true
  end
end

このマイグレーションを実行すると

  • articlesテーブルにuser_idカラムが追加
  • user_idカラムにインデックスが設定
  • user_idカラムに外部キー制約が設定され、user_idにはusersテーブルの存在するidしか入らないようになる設定

articlesのmodelとテーブル作成

modelとテーブルの作成は以下のようにします。

$ rails g model Article title:string body:text user:references

user:referencesの部分は本来user_id:bignitを作成するところをuser:referencesで作成


class CreateArticles < ActiveRecord::Migration[6.0]
  def change
    create_table :articles do |t|
      t.string :title
      t.text :body
      t.references :user, null: false, foreign_key: true

      t.timestamps
    end
  end
end

外部キー制約(小学生にもわかるように解説)

学校の図書室で本を借りるとします。そこでは、どの本を誰が借りているかを知るために管理したいと思うはずです。 管理する上で次の2つのリストがあるとします。

  • 生徒のリスト 学校のすべての生徒の名前が書いてあるリスト

  • 貸出リスト どの本を誰が借りているかが書いてあるリスト 貸出リストには、次のような情報が書かれています。

  • 借りている本の名前

  • 本を借りた生徒の名前

外部キー制約の役割

「貸出リストに書かれている生徒の名前は、生徒のリストにある名前だけにしなければならない」というルールのようなものです。これによって、次のようなことが防げます。

  • 存在しない生徒の名前を書くこと 貸出リストにいない生徒の名前を書くと、誰が本を借りたのか分からない
  • 間違った名前を書くこと 例えば、「花道」という生徒がいないのに、間違って「花道」と書いてしまうみたいな

外部キーはどうして必要なのか?

このルールがないと、いろいろな問題が起きます。

  • だれが本を借りたかがわからなくなる。
  • 名前が間違っていると、本を返してもらうときに困る。 外部キー制約は、このような問題を防ぎ、データを正しく保つための大切なルールです。

資料

ChatGPT参照