Search code examples
ruby-on-railsrubyrails-activerecordsingle-table-inheritance

Rails: Circular dependency in connected STI classes


I have two classes: Category and Meter. Like a Category, a Meter has a name and is used to categorise various Bills. The difference between them is that a Meter has several more connections and can have another Category or Meter as its parent.

I've implemented this domain using single-table inheritance, but when I'm trying to run the console or the tests or the server I get the 'load_missing_constant': Circular dependency detected while autoloading constant Meter error (the full trace is here.)

Here are the classes in question:

meter.rb:

class Meter < Category
  belongs_to :parent, class_name: Category
  has_many :meter_values, dependent: :destroy
  has_many :tariffs, dependent: :destroy
  validates :init_meter, presence: true
  validates :init_meter, numericality: { greater_than_or_equal_to: 0.0 }


  def current_tariff
    tariffs.first
  end
end

category.rb:

class Category < ActiveRecord::Base
  has_many :bills, dependent: :destroy
  has_many :children, class_name: Meter, inverse_of: :parent, foreign_key: :parent_id

  validates_associated :bills
  validates :name, presence: true
end

Solution

  • Category and Meter both reference each other in their class definitions, so neither can load without the other being loaded first. If you put the class_name in quotes you should be good:

    has_many :children, class_name: 'Meter', ...
    

    My spidey sense is a little tingly, though, with your domain model. You may want to revisit your database design and see if there's another table that should be holding some or all of what is in Meter rather than using STI.