Circular dependency detected while autoloading constant (ActiveRecord)

852 views Asked by At

I have manually specified the relationships in the models (haven't found a way how to automatically generate them from a ERD model or an existing database) and than tried to generate a migration containing the FKs using the immigrant gem. I am getting:

rails generate immigration AddKeys
lib/active_support/dependencies.rb:478:in `load_missing_constant': Circular dependency detected while autoloading constant Assignment (RuntimeError)
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451@railstutorial_rails_4_0/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:180:in `const_missing'
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451@railstutorial_rails_4_0/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:512:in `load_missing_constant'
from /Users/nnikolo/.rvm/gems/ruby-2.0.0-p451@railstutorial_rails_4_0/gems/activesupport-4.1.5/lib/active_support/dependencies.rb:180:in `const_missing'

Here is the code for the models:

class Account < ActiveRecord::Base
  include Person
  include Contact
  has_many :coworkers, :class_name => 'Coworker'
  has_many :customers, :class_name => 'Customer'
  has_many :locations, :class_name => 'Location'
  has_many :appointment_types, :class_name => 'AppointmentType'

  before_create :create_remember_token
  has_secure_password
  validates :password, length: { minimum: 6 }
  validates :rem_notice_hrs, presence: true
  validates :rem_notice_hrs, numericality: true
  validates :rem_text, presence: true
  validates :email, presence: true, length: { maximum: 255 },
        format: { with: VALID_EMAIL_REGEX }

  after_initialize :init

  def Account.new_remember_token
    SecureRandom.urlsafe_base64
  end

  def Account.digest(token)
    Digest::SHA1.hexdigest(token.to_s)
  end

  private
    def init
      if self.new_record?
        if self.rem_notice_hrs.nil?
          self.rem_notice_hrs = 24
        end
        if self.rem_text.nil?
          if self.company.nil?
            self.rem_text = "Dear [customer title: automatic] [customer family name: automatic], this is a reminder of your appointment with %{title} %{family_name} on [date/time]."
          else
            self.rem_text = "Dear [title] [customer family name], this is a reminder of your appointment with %{company} on [date/time]."
          end
        end
      end
    end

    def create_remember_token
      self.remember_token = User.digest(User.new_remember_token)
    end
end

class Location < ActiveRecord::Base
  belongs_to :coworker, :class_name => 'Coworker', :foreign_key => :wor_id
  belongs_to :appointment, :class_name => 'Appointment', :foreign_key => :app_id
  #optional deletion flag:
  validates_inclusion_of :deleted, in: [true, false]
end

class Coworker < ActiveRecord::Base
  include Person
  validates_inclusion_of :deleted, in: [true, false]
  belongs_to :account, :class_name => 'Account', :foreign_key => :acc_id
  has_many :assignments
end

class Location < ActiveRecord::Base
  belongs_to :coworker, :class_name => 'Coworker', :foreign_key => :wor_id
  belongs_to :appointment, :class_name => 'Appointment', :foreign_key => :app_id
  validates_inclusion_of :deleted, in: [true, false]
end

class Appointment < ActiveRecord::Base
  belongs_to :customer, :class_name => 'Customer', :foreign_key => :cus_id
  belongs_to :location, :class_name => 'Location', :foreign_key => :loc_id
  belongs_to :appointment_type, :class_name => 'AppointmentType', :foreign_key => :app_type_id
  has_many :assignments, :class_name => 'Assignment'
  has_many :reminders, :class_name => 'Reminder'

  validates_date :from, :on_or_after => :today
  validates_date :till, :on_or_after => :from
  validates_inclusion_of :deleted, in: [true, false]

  attr_accessor :title
end

Some of the models above implement the following concerns:

module Contact
  extend ActiveSupport::Concern
  extend ActiveModel::Naming
  include ActiveModel::Conversion
  include ActiveModel::Validations
  # phone attribute
  included do
    validates :phone, presence: true
    validates :phone, numericality: true
    attr_accessor :company
  end
  #email regex
    VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
end

module Person
  extend ActiveSupport::Concern
  extend ActiveModel::Naming
  include ActiveModel::Conversion
  include ActiveModel::Validations
  included do
   # deleted flag attribute
   attr_accessor :first_name, :family_name, :title
  end
end

Can you tell what's going wrong here?

1

There are 1 answers

0
Nick On

This is a classical example of a copy-paste mess - I've copied the code of Location.rb into Assignment.rb, edited it but forgot to re-name the class. So I end up having two Location models - in 2 different rb files. Doh!