Search code examples
ruby-on-railsactiverecord

How to specify the actual foreign key in a parent-child relationship when the parent is defined via STI in Rails 5.2?


I use STI in my application, so that Procedure and DataProcess models both inheritate from the BusinessProcess class:

class BusinessProcess < ApplicationRecord
end

class Procedure < BusinessProcess
end

class DataProcess < BusinessProcess
  has_many :treatments, inverse_of: :parent, dependent: :destroy
end

class Treatment < ApplicationRecord
  belongs_to :parent, class_name: "DataProcess", foreign_key: "business_process_id"
end

All works as expected, until I issue a query such as @data_process.treatments.first from the show view. This raises the following error:

*** ActiveRecord::StatementInvalid Exception: PG::UndefinedColumn: FEHLER:  Spalte treatments.data_process_id existiert nicht
LINE 1: SELECT  "treatments".* FROM "treatments" WHERE "treatments"....
                                                       ^
: SELECT  "treatments".* FROM "treatments" WHERE "treatments"."data_process_id" = $1 ORDER BY "treatments"."id" ASC LIMIT $2

It looks like Rails does not take in consideration that the foreign key is business_process_id, but generates it's own, forgetting about the STI context.

Is there a way to be more specific?


Solution

  • You have to specify foreign_key on has_many association:

    has_many :treatments, inverse_of: :parent, dependent: :destroy, foreign_key: "business_process_id"
    

    Otherwise, Rails assumes foreign key of DataProcess model is data_process_id column on Treatment.

    Reference: https://guides.rubyonrails.org/association_basics.html#options-for-has-many-foreign-key