Skip to content

Instantly share code, notes, and snippets.

@adamcrown
Created October 18, 2018 06:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save adamcrown/937bde34ea6817bb7b1a196fbde39caa to your computer and use it in GitHub Desktop.
Save adamcrown/937bde34ea6817bb7b1a196fbde39caa to your computer and use it in GitHub Desktop.
Find polymorphic associations to a model
# Finds all column that reference a certain model name via a polymorphic association.
# This is helpful when renaming a table, because if you don't update the model names
# in these polymorphic belongs_to associations they will break.
class PolymorphicBelongsToFinder
POLYMORPHIC_COLUMN_MATCH = /_type\Z/.freeze
def initialize(old_model_name)
@old_model_name = old_model_name
end
# Columns that reference the old model
def problematic_columns
problem_cols = []
all_models.select do |model|
polymorphic_columns_for(model).each do |col|
if model.pluck(col).include?(old_model_name)
problem_cols << model.column_for_attribute(col)
end
end
end
problem_cols
end
def print_report
cols = problematic_columns
if cols.any?
puts "#{cols.count} polyorphic association(s) to #{old_model_name} were found"
cols.each do |col|
puts "#{col.table_name}.#{col.name} references #{old_model_name}"
end
else
puts "No polyorphic associations to #{old_model_name} were found"
end
nil
end
private
attr_reader :old_model_name
def all_models
(ApplicationRecord.subclasses | ActiveRecord::Base.subclasses).reject(&:abstract_class)
end
def polymorphic_columns_for(model)
# Really just columns who's name matches polymorphic belongs_to naming
# TODO: improve this to detect non-standard naming
model.column_names.grep(POLYMORPHIC_COLUMN_MATCH)
end
end
# Example:
# PolymorphicBelongsToFinder.new('OldModelName').print_report
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment