scottwillson/racing_on_rails

View on GitHub
app/models/categories/cleanup.rb

Summary

Maintainability
A
55 mins
Test Coverage
# frozen_string_literal: true

module Categories
  module Cleanup
    extend ActiveSupport::Concern

    included do
      def self.cleanup!(commit_changes = true)
        transaction do
          logger.info "#{Category.count} categories before cleanup"

          destroy_unused!
          cleanup_names!

          logger.info "#{Category.count} categories after cleanup"

          raise ActiveRecord::Rollback unless commit_changes
        end
        true
      end

      def self.destroy_unused!
        Category.all.find_each do |category|
          unless category.in_use?
            logger.info "Destroy unused Category #{category.id} #{category.name}"
            category.destroy!
          end
        end
        true
      end

      def self.cleanup_names!
        # Whitespace cleanup deletes duplicate categories
        Category.all.find_each do |category|
          normalized_name = Category.normalized_name(category.name)
          next unless category.name != normalized_name

          existing_category = Category.where(name: normalized_name).where.not(id: category.id).first
          if existing_category
            category.replace_with existing_category
          else
            logger.info "Cleanup Category name from '#{category.name}' to '#{normalized_name}'"
            category.update! raw_name: normalized_name
          end
        end
        true
      end
    end

    def in_use?
      Category.exists?(parent_id: id) ||
        Discipline.joins(:bar_categories).exists?("discipline_bar_categories.category_id" => id) ||
        Race.exists?(category_id: id) ||
        Result.exists?(category_id: id)
    end

    def replace_with(existing_category)
      logger.info "Replace #{id} '#{name}' with #{existing_category.id} '#{existing_category.name}'"
      Category.where(parent_id: id).update_all(parent_id: existing_category.id)
      Discipline.connection.execute "update discipline_bar_categories set category_id = #{existing_category.id} where category_id = #{id}"
      Race.where(category_id: id).update_all(category_id: existing_category.id)
      Result.where(category_id: id).update_all(category_id: existing_category.id)
      destroy!
    end
  end
end