はじめに
ユーザー(reviewer)がユーザー(reviewee)をレビューする機能を実装するために行った、usersテーブルから2つの外部キーを取得する方法について記述したいと思います。
外部キーを複数取得
通常、外部キーを取得する際は
t.references :user, foreign_key: true
上記のようにすることで、参照先(usersテーブル)をもとにテーブル内に user_id というカラムが作成されます。
railsのデフォルトでは、外部キーを表す命名規則が${model名}_idと決まっているため、同じmodelを参照する外部キーがそのままでは設定できない。
今回の場合は、同じテーブル内に複数の外部キーを取得したいので
class CreateReviews < ActiveRecord::Migration[6.0]
def change
create_table :reviews do |t|
t.integer :score, null: false
t.text :content
t.references :reviewer, foreign_key: {to_table: :users}
t.references :reviewee, foreign_key: {to_table: :users}
t.timestamps
end
end
end
ポイントは {to_table: :users} の箇所で、
references 型カラムを定義している部分でオプション :foreign_key にサブオプション :to_table を参照先テーブル名とともに指定することで、正しく参照先テーブルを参照し、テーブル(reviewsテーブル)が作成することができます。
アソシエーション
modelの belongs_to/has_many で foreign_key を明示的に指定する。
class User < ApplicationRecord
(省略)
has_many :reviewer_reviews, class_name: 'Review', :foreign_key => 'reviewer_id'
has_many :reviewee_reviews, class_name: 'Review', :foreign_key => 'reviewee_id'
(省略)
end
class Review < ApplicationRecord
belongs_to :reviewer, :class_name => 'User', :foreign_key => 'reviewer_id'
belongs_to :reviewee, :class_name => 'User', :foreign_key => 'reviewee_id'
end
has_many :reviewer_reviews, class_name: 'Review', :foreign_key => 'reviewer_id'
Reviewテーブル(class_name: 'Review')の
reviewer_id(:foreign_key => 'reviewer_id')を
reviewer_reviews(has_many :reviewer_reviews)として取得できる。
参考
https://qiita.com/kymmt90/items/03cb9366ff87db69f539
https://qiita.com/takeoverjp/items/bb56d6a8eae191cd3732