Skip to content

Instantly share code, notes, and snippets.

@coorasse
Created November 13, 2024 20:47
Show Gist options
  • Save coorasse/6d82dd182443b7a94ddc11c449fd57ce to your computer and use it in GitHub Desktop.
Save coorasse/6d82dd182443b7a94ddc11c449fd57ce to your computer and use it in GitHub Desktop.
Ruby On Rails - Rake task to check for missing foreign keys
namespace :db do
desc "Check for missing foreign keys and generate migration commands"
task check_keys: :environment do |_task, _args|
Rails.application.eager_load!
schema = ApplicationRecord.connection
missing_foreign_keys = []
puts ApplicationRecord.descendants
# Loop through each ActiveRecord model
ApplicationRecord.descendants.each do |model|
puts "iterating on #{model}"
next if model.abstract_class? || !model.table_exists?
# Check for belongs_to associations
model.reflect_on_all_associations(:belongs_to).each do |assoc|
next if assoc.polymorphic?
puts "checking #{model}.#{assoc.name}"
foreign_key = assoc.foreign_key
target_table = assoc.klass.table_name
# Check if the foreign key exists in the database schema
foreign_key_exists = schema.foreign_keys(model.table_name).any? { |fk| fk.options[:column] == foreign_key }
# Check if the column is an integer to suggest a bigint conversion
column_type = model.columns_hash[foreign_key]&.sql_type
unless foreign_key_exists
if column_type == "integer"
missing_foreign_keys << " # Change column type to bigint before adding foreign key:\n" \
" change_column :#{model.table_name}, :#{foreign_key}, :bigint\n"
end
missing_foreign_keys << " add_foreign_key :#{model.table_name}, :#{target_table}, column: :#{foreign_key}"
end
end
end
if missing_foreign_keys.empty?
puts "No missing foreign keys found."
else
puts "Add these commands to a migration:\n\n"
puts missing_foreign_keys.join("\n")
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment