Railsで「PG::UndefinedColumn: ERROR: xxx.xxx_id does not exist」

Docker x Rails6 APIモードでアソシエーション設定時に「外部キーがない」といったエラーが表示された。
原因はアソシエーションの設定誤りだった。

設定内容

断片的な情報になるが、前提となる設定内容は以下のとおり。

ER図:以下の赤枠部分が対象

ER図:外部キーの設定状況

(親モデル)api/app/models/agenda_item.rb

class AgendaItem < ApplicationRecord
  belongs_to :agenda_group
  has_many :agenda_details, dependent: :destroy
  has_one :document_agenda_item, dependent: :destroy
end

(子モデル)api/app/models/document_agenda_item.rb

class DocumentAgendaItem < ApplicationRecord
  belongs_to :document_group
  has_one :agenda_item
end

api/app/controllers/v1/document_agenda_items_controller.rb

  def index
    @document_agenda_items = DocumentAgendaItem.all

    render json: @document_agenda_items, include: [:agenda_item]
  end

現象

indexにアクセスすると(localhost:3000/v1/document_agenda_items/)、以下のエラーが表示される。

api_1  | ActiveRecord::StatementInvalid (PG::UndefinedColumn: ERROR:  column agenda_items.document_agenda_item_id does not exist
api_1  | LINE 1: SELECT "agenda_items".* FROM "agenda_items" WHERE "agenda_it...

原因

アソシエーションの設定ミス。DBの外部キーの設定とアソシエーションをあわせする必要がある。

  • has_oneは相手側に外部キーがある場合
  • belongs_toは自分に外部キーがある場合
4.2 has_one関連付けの詳細
has_one関連付けは他のモデルと1対1対応します。データベースの観点では、この関連付けでは相手のクラスが外部キーを持ちます。相手ではなく自分のクラスが外部キーを持っているのであれば、belongs_toを使うべきです。

引用元:Railsガイド

対応

自分(子モデル)が親モデルの外部キーを持っているため、has_oneではなく、belongs_toを使う。

api/app/models/document_agenda_item.rb

class DocumentAgendaItem < ApplicationRecord
  belongs_to :document_group
    # has_one :agenda_item # ←コメントアウト
    belongs_to :agenda_item # ←追加
end