class ActiveRecordDoctor::AddIndexesGenerator

Generate migrations that add missing indexes to the database.

Constants

INPUT_LINE

Public Instance Methods

create_migrations() click to toggle source
# File lib/generators/active_record_doctor/add_indexes/add_indexes_generator.rb, line 9
def create_migrations
  migration_descriptions = read_migration_descriptions(path)
  now = Time.now

  migration_descriptions.each_with_index do |(table, indexes), index|
    timestamp = (now + index).strftime("%Y%m%d%H%M%S")
    file_name = "db/migrate/#{timestamp}_index_foreign_keys_in_#{table}.rb"
    create_file(file_name, content(table, indexes).tap { |x| puts x })
  end
end

Private Instance Methods

add_index(table, columns) click to toggle source
# File lib/generators/active_record_doctor/add_indexes/add_indexes_generator.rb, line 64
def add_index(table, columns)
  connection = ActiveRecord::Base.connection

  index_name = connection.index_name(table, columns)
  if index_name.size > connection.index_name_length
    "    add_index :#{table}, #{columns.inspect}, name: '#{index_name.first(connection.index_name_length)}'"
  else
    "    add_index :#{table}, #{columns.inspect}"
  end
end
add_indexes(table, indexes) click to toggle source
# File lib/generators/active_record_doctor/add_indexes/add_indexes_generator.rb, line 58
def add_indexes(table, indexes)
  indexes.map do |columns|
    add_index(table, columns)
  end.join("\n")
end
content(table, indexes) click to toggle source
# File lib/generators/active_record_doctor/add_indexes/add_indexes_generator.rb, line 45
    def content(table, indexes)
      # In order to properly indent the resulting code, we must disable the
      # rubocop rule below.

      <<MIGRATION
class IndexForeignKeysIn#{table.camelize} < ActiveRecord::Migration#{migration_version}
  def change
#{add_indexes(table, indexes)}
  end
end
MIGRATION
    end
migration_version() click to toggle source
# File lib/generators/active_record_doctor/add_indexes/add_indexes_generator.rb, line 75
def migration_version
  if ActiveRecord::VERSION::STRING >= "5.1"
    "[#{ActiveRecord::Migration.current_version}]"
  else
    ""
  end
end
read_migration_descriptions(path) click to toggle source
# File lib/generators/active_record_doctor/add_indexes/add_indexes_generator.rb, line 25
def read_migration_descriptions(path)
  tables_to_columns = Hash.new { |hash, table| hash[table] = [] }

  File.readlines(path).each_with_index do |line, index|
    next if line.blank?

    match = INPUT_LINE.match(line)
    if match.nil?
      raise("cannot extract table and column name from line #{index + 1}: #{line}")
    end

    table = match[1]
    columns = match[2].split(",").map(&:strip)

    tables_to_columns[table] << columns
  end

  tables_to_columns
end