class ActiveRecord::DataIntegrity::HasMany::ForeignKey

Checks foreign key presence to the parent table of belongs_to association

Public Instance Methods

call() click to toggle source
# File lib/active_record/data_integrity/cop/has_many/foreign_key.rb, line 10
def call
  results = associations.map do |association|
    valid?(association)
  end

  results.none?(&:!)
end

Private Instance Methods

associations() click to toggle source
# File lib/active_record/data_integrity/cop/has_many/foreign_key.rb, line 33
def associations
  model
    ._reflections
    .values
    .select { |association| association.is_a?(ActiveRecord::Reflection::HasManyReflection) }
    .reject(&:polymorphic?)
end
foreign_key?(association) click to toggle source
# File lib/active_record/data_integrity/cop/has_many/foreign_key.rb, line 41
def foreign_key?(association)
  to_table = model.table_name
  connection.foreign_keys(association.class_name.constantize.table_name).any? do |foreign_key|
    foreign_key.to_table == to_table && foreign_key.options.fetch(:primary_key) == 'id'
  end
end
valid?(association) click to toggle source
# File lib/active_record/data_integrity/cop/has_many/foreign_key.rb, line 20
def valid?(association)
  success = foreign_key?(association)
  unless success
    from_table = association.class_name.constantize.table_name
    log("has_many #{association.name} but has no foreign key from #{from_table}.id")
  end
  progress(success, 'F')

  success
rescue NameError
  log("Error processing #{model.name}.#{association.name}")
end