#Railsで別名の外部キーを設定する方法
1対多のリレーションで別名の外部キーのカラム名を設定した記録です。
##背景
通常、1対多のリレーションではTeamモデルにはuserと書くことが多いが、
Teamの所有者であることを強調したいので別名カラム__owner__を設定する必要がありました。
目次
動作環境
OS : macOS Mojave 10.14.6
ruby : 2.6.3p62
rails : 5.2.4
結論
以下のステップで実現できました。
STEP1.別名カラムをTeamsモデルに作成
マイグレーション
1. 新規テーブルの場合
migrationfile1.rb
class CreateTeams < ActiveRecord::Migration[5.2]
def change
create_table :teams do |t|
t.string :name
t.integer :owner_id, index: true
t.timestamps
end
add_foreign_key :teams, :users, column: :owner_id
end
end
2. 既存テーブルに追加する場合
migrationfile.rb
class AddUserRefToTeams < ActiveRecord::Migration[5.2]
def change
add_reference :teams, :owner, foreign_key: { to_table: :users }
end
end
マイグレーションの実行
rails db:migrate
schema
create_table "teams", force: :cascade do |t|
t.string "name"
t.integer "owner_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "icon"
t.index ["owner_id"], name: "index_teams_on_owner_id"
end
add_foreign_key "teams", "users", column: "owner_id"
STEP2.UserモデルとTeamモデルにリレーションを設定
user.rb
class User < ApplicationRecord
has_many :teams, foreign_key: :owner_id
end
team.rb
class Team < ApplicationRecord
belongs_to :owner, class_name: 'User', foreign_key: :owner_id
end
結果
以下のようにteam.ownerでチーム所有者のuser情報が取り出せています。
ポイント
リレーションにクラス名をつけること
userカラムの場合はteamモデルにclass_nameはつけませんが、
別名の場合はclass_nameをつけないとエラーになってしまいました。
belongs_to :owner, class_name: 'User', foreign_key: :owner_id
おわりに
今回の件で以下のことを学びました。
別名外部キーの設定方法