Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ActiveRecord::HasManyThroughOrderError

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
like image 653
Cj Monteclaro Avatar asked May 17 '17 01:05

Cj Monteclaro


3 Answers

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
like image 137
Mark Robinson Avatar answered Sep 18 '22 11:09

Mark Robinson


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.

like image 41
Throw Away Account Avatar answered Sep 21 '22 11:09

Throw Away Account


Make sure you don't have another redundant has_one :intermediary in your Policy model. Got the same error after update.

like image 30
Nick Pridorozhko Avatar answered Sep 19 '22 11:09

Nick Pridorozhko