1
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【Rails】foreign_key: true を記述するかしないか

Last updated at Posted at 2024-02-18

はじめに

Userモデルと紐づいたProfileモデルを作成しようとしているところ。
User:Profile = 1:1 の関係にしたい為、t.referencesを追記。

20240218073445_create_profiles
class CreateProfiles < ActiveRecord::Migration[6.0]
  def change
    create_table :profiles do |t|
      t.references :user, null: false
      t.timestamps
    end
  end
end

ここで疑問に思った事は、foreign_key: trueをとりあえず追加しておけ。という記事が多くて理由はなんやねん、という事。これについて解説。
foreign_keyについての詳細は省略。

RubyとRailsのバージョン

  • Ruby 3.1.3
  • Rails 6.0.6.1

【結論】Railsの命名規則に従っていれば基本は不要

今回のケースのような場合はActive RecordがUserモデルと関連性があるって事は外部キーは'user_id'だよね。という感じで推測して自動でカラムを作成してくれます。(賢すぎ)

foreign_key: trueが必要な場合とは?

Railsの命名規則から外れているケース(例えば自己結合を行う時)
User間のフォロー機能を実装したいとして、User:User = 1:1とする。
この場合中間テーブルとしてrelationshipを作成するとして、このまま何も指定しないとuser_idが2つ出来てしまう(どっちがフォローしているのか不明になってしまう)
これを解決する為にfollwing_idとfollower_idみたいにしたい時!!
(具体例)
user1→user2をフォローする時にfollwing_id = 1, follower_id = 2としたいが下記のようにforeign_key: { to_table: :users } foreign_keyを指定しなければ、Active Recodeはuserテーブルから外部キーを推測する事ができないはず。(references :userでない為)

20230815011533_create_relationships
class CreateRelationships < ActiveRecord::Migration[6.0]
  def change
    create_table :relationships do |t|
      t.references :following, null: false, foreign_key: { to_table: :users }
      t.references :follower, null: false, foreign_key: { to_table: :users }
      t.timestamps
    end
  end
end

GPTにも聞いてみた

最後に

自分なりに色々調べましたが、最後の方の説明が難しくて雑になってしまった感。。
間違っている部分、細く部分あれば教えてください。

参考文献

https://railsguides.jp/association_basics.html
https://qiita.com/ryouzi/items/2682e7e8a86fd2b1ae47

1
3
1

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
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?