scottwillson/racing_on_rails

View on GitHub
app/models/events/previous.rb

Summary

Maintainability
A
1 hr
Test Coverage
# frozen_string_literal: true

module Events
  module Previous
    extend ActiveSupport::Concern

    def previous?
      previous_year.present?
    end

    def previous_year
      exact_match = Event.find_by(name: name, year: year - 1)
      return exact_match if exact_match

      diff, event = previous_best_match
      return unless event
      return event if diff <= 2
      return event if similar_promoter_name?(event)
      return event if diff < 5 && similar_dates?(event)
    end

    # return diff (0 = perfect match, > 0 partial match), event
    def previous_best_match
      match = previous_year_events_with_similar_names.first
      [match.try(:first), match.try(:last).try(:first)]
    end

    def previous_year_events_with_similar_names
      Event.where(year: year - 1).group_by { |e| DamerauLevenshtein.distance(name, e.name) }.sort_by(&:first)
    end

    def add_races_from_previous_year
      categories = races.map(&:category)

      previous_year.races
                   .reject { |r| r.category.in? categories }
                   .each { |r| add_race_from_previous_year(r) }
    end

    def add_race_from_previous_year(race)
      races.create! category: race.category
    end

    def similar_promoter_name?(event)
      event.promoter_name &&
        promoter_name &&
        DamerauLevenshtein.distance(event.promoter_name, promoter_name) <= 3
    end

    def similar_dates?(event)
      ((event.date.month * 12 + event.date.day) - (date.month * 12 + date.day)).abs < 10
    end
  end
end