Skip to content

Instantly share code, notes, and snippets.

@ddonahue99
Created July 12, 2012 15:20
Show Gist options
  • Save ddonahue99/3098825 to your computer and use it in GitHub Desktop.
Save ddonahue99/3098825 to your computer and use it in GitHub Desktop.
rake db:remove_orphans - detects orphans based on belongs_to relations and prompts to remove
namespace :db do
desc "Remove orphans"
task :remove_orphans => :environment do
Dir[Rails.root + "app/models/**/*.rb"].each do |path|
require path
end
ActiveRecord::Base.send(:descendants).each do |model|
model.reflections.each do |association_name, reflection|
if reflection.macro == :belongs_to
delete_all_like_this = false
# Select only the id and the foreign key for this association
select = ['id', reflection.foreign_key]
# Also select the foreign type for this association if it is polymorphic
select << reflection.foreign_type if reflection.options[:polymorphic]
# Load all records and join the association we are checking to cut down on queries
query = model
.select(select.join(','))
.includes(association_name)
.where("#{reflection.foreign_key} IS NOT NULL")
query.find_each do |model_instance|
if model_instance.send(association_name).nil?
puts model_instance.inspect
if delete_all_like_this
model_instance.destroy
else
puts "\n#{model.name}'s #{association_name} (id: #{model_instance.send(reflection.foreign_key)}) is nil, delete? [y/n/a]: "
case STDIN.gets.strip
when "y", "Y"
model_instance.destroy
when "a", "A"
model_instance.destroy
delete_all_like_this = true
end
end
end
end
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment