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?
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!