LoginSignup
4
0

More than 1 year has passed since last update.

primary keyをid以外にしたときのforeign keyとassociationの設定に詰まった

Last updated at Posted at 2023-03-17

普段あまりやらないですが、primary keyをid以外にした時に詰まったのでメモです。

サンプルコード

以下のようにprimary_keyがidではないusersテーブルがあります。

db/schema.rb
# primary_keyがidのusersテーブル
#    create_table "users", force: :cascade do |t|
#      t.string "name", null: false
#    end

# primary_keyをuuidにしたいとき
   create_table "users", primary_key: "uuid", id: :string, force: :cascade do |t|
     t.string "name", null: false
   end

そして、以下のようにarticlesテーブルを作成します。

この際、referencesを使うと、primary_keyの指定ができませんでした。
そのため、user_uuidテーブルとforeign_keyを個別に指定します。

また、うっかりミスなのですが、t.references :userからt.foreign_key :usersに変える時に、users と、テーブル名に書き換え忘れていました。

 class CreateArticles < ActiveRecord::Migration[7.0]
   def change
     create_table :articles do |t|
-      t.references :user, null: false, foreign_key: true
+      t.string :user_uuid, null: false
+      t.foreign_key :users, column: :user_uuid, primary_key: :uuid
       t.string :title, null: false
       t.text :body, null: false
       t.timestamps

+      t.index :user_uuid
     end
   end
 end

また、このままだとuser.articlesを取得しようとした時に、article.user_idを参照したりしてしまうので、associationの設定も必要です。
以下のようにbelongs_to, has_manyを設定するとuser.articles, article.userの設定ができました。

class Article < ApplicationRecord
-  belongs_to :user
+  belongs_to :user, primary_key: :uuid, foreign_key: :user_uuid
end

class User < ApplicationRecord
-  has_many :articles
+  has_many :articles, foreign_key: :user_uuid
end

参考

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