Rails のマイグレーション機能で使える、references は簡単にリレーション用のカラムを追加することができるものです。

例えば…

User モデルと Article モデルというのがあったとします。

    class User < ApplicationRecord
      has_many :articles
    end
    class Article < ApplicationRecord
      belongs_to :user
    end

こういう状態の時 migration ファイルで

    def change
      create_table :articles do |t|
        t.string :title # 記事タイトル
        t.text :body    # 記事本文
        t.references :user
      end
    end

こうすると articles テーブルに user_id カラムが追加されます。
user_id カラムが追加されるので、user_id 明記して書くのとほぼ同義ですね。

    def change
      create_table :articles do |t|
        t.string :title # 記事タイトル
        t.text :body    # 記事本文
        t.integer :user_id
      end
    end

「ほぼ」と書いたのは、references と使った場合は追加した user_id カラムに対して index を自動で作ってくれるのですが、 user_id を直接書いた場合は index は自分で追加する命令を書かないといけません。

index が何者かという説明は難しいのですが、データベースの検索のパフォーマンスをあげるために必要な仕組みという理解でとりあえず大丈夫です。

index があってもなくても同じ挙動をしますが、データ量が増えてきた場合にパフォーマンスに影響が出てくるようになります。

references の他の仕組み

references にはカラムをただ追加するだけでなく、いくつかオプションがあります。
その中の一つが foreign_key の指定です。

    t.references :user, foreign_key: true

とすることで、追加したカラムに対して外部キー制約をつけることができます。

外部キー制約はRails の機能というよりは MySQL や PostgreSQL といったデータベース側の機能で、外部キー制約を使うことで、データの構造をより厳格にすることができるようになるので、こうしたリレーションをさせるための id に対しては基本的にはつけた方が良いです。

ただし、外部キー制約があると困るパターンもあるのでどういう挙動をするのかというのは理解した上でつけるべきです。

例えば…
ユーザーが投稿した記事は、ユーザーが退会してもそのまま残したい。
ということを考えている場合に…

先ほどの User モデルと Article モデルを例で、articles テーブルの user_id に対して外部キー制約をつけてみます。

    def change
      create_table :articles do |t|
        t.string :title # 記事タイトル
        t.text :body    # 記事本文
        t.references :user, foreign_key: true
      end
    end

外部キー制約をつけたので、articles テーブルの user_id のユーザーは必ずデータとして存在していなくてはなりません。

そんな中ユーザーが退会して users テーブルのデータを消そうとすると、外部キー制約でエラーになってしまいます。
エラーにならないようにするためには、user を消す前に user にひもづく article を全て消さなければなりません。
そうすると、最初に書いた

ユーザーが投稿した記事は、ユーザーが退会してもそのまま残したい。

というのが実現できなくなってしまうので、こうした場合は外部キー制約はつけてはいけない、ということになりますね。