Skip to content

Instantly share code, notes, and snippets.

@michel-zimmer
Created May 30, 2017 20:32
Show Gist options
  • Save michel-zimmer/d93bb472824c05dc5a327ae8ab81161d to your computer and use it in GitHub Desktop.
Save michel-zimmer/d93bb472824c05dc5a327ae8ab81161d to your computer and use it in GitHub Desktop.
Rails task printing tables sorted by foreign key dependencies
namespace :db do
desc "Prints tables sorted by foreign key dependencies"
task fk: :environment do
connection = ActiveRecord::Base.connection
ignored_tables = [ActiveRecord::Base.schema_migrations_table_name, ActiveRecord::Base.internal_metadata_table_name]
fs_names = connection.tables.sort - ignored_tables
foreign_keys = fs_names
.map { |table_name| connection.foreign_keys(table_name) }.flatten
.map { |foreign_key| { 'from': foreign_key.from_table, 'to': foreign_key.to_table } }.uniq
print " tables: "; p fs_names
print " foreign keys: "; p foreign_keys
def sort_by_dependencies(unsorted, dependencies)
left = unsorted
sorted = []
dependencies = dependencies.select{ |d| left.include?(d[:from]) && left.include?(d[:to]) }
while !left.empty?
exclude = dependencies.map{ |d| d[:from] }.uniq
add = left - exclude
sorted = sorted + add
if add.empty?
warn "Circular dependencies"
return unsorted
end
left = left - add
dependencies = dependencies.select{ |d| !add.include?(d[:to]) }
end
sorted
end
print "sorted tables: "; p sort_by_dependencies(fs_names, foreign_keys)
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment