Docker x Rails6 APIモードでアソシエーション設定時に「外部キーがない」といったエラーが表示された。
原因はアソシエーションの設定誤りだった。
Agenda
設定内容
断片的な情報になるが、前提となる設定内容は以下のとおり。
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