I have a has_one association between 3 models, but it have an error that says "ActionView::Template::Error (Cannot have a has_many :through association 'Policy#intermediary' which goes through 'Policy#invoice' before the through association is defined.)"
policy model
class Policy < ApplicationRecord
self.table_name = "gipi_polbasic"
self.primary_key = "policy_id"
has_one :invoice
has_one :intermediary, through: :invoice, foreign_key: :intrmdry_intm_no
intermediary model
class Intermediary < ApplicationRecord
self.table_name = "giis_intermediary"
self.primary_key = "intm_no"
has_one :invoice, foreign_key: :intrmdry_intm_no
belongs_to :policy, foreign_key: :policy_id
invoice model
class Invoice < ApplicationRecord
self.table_name = "gipi_comm_invoice"
self.primary_key = "intrmdry_intm_no"
belongs_to :policy, foreign_key: :policy_id
belongs_to :intermediary, foreign_key: :intrmdry_intm_no
For anyone else - see their thread https://github.com/rails/rails/issues/29123
What solved it for me was to switch the order of the has_ones
has_one :intermediary, through: :invoice, foreign_key: :intrmdry_intm_no
has_one :invoice
Here's a technique for finding duplicate association definitions, in case you have models made up of several monkey patches.
First, find the has_many
method:
ActiveRecord::Associations::ClassMethods.instance_method(:has_many).source_location
Then, edit that file:
def has_many(name, scope = nil, options = {}, &extension)
$has_manies ||= {} # <- Added
$has_manies[[name, self]] ||= [] # <- Added
$has_manies[[name, self]] << [options,caller[0]] # <- Added
reflection = Builder::HasMany.build(self, name, scope, options, &extension)
Reflection.add_reflection self, name, reflection
end
Then catch the HasManyThroughOrderError and start a debugger. Evaluate this:
$has_manies[[:intermediary, Policy]]
You'll see not only whether that association is defined more than once, but also where the definitions happened.
Make sure you don't have another redundant has_one :intermediary
in your Policy
model. Got the same error after update.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With