dawarich/app/services/countries_and_cities.rb

58 lines
1.4 KiB
Ruby

# frozen_string_literal: true
class CountriesAndCities
def initialize(points)
@points = points
end
def call
grouped_records = group_points
mapped_with_cities = map_with_cities(grouped_records)
filtered_cities = filter_cities(mapped_with_cities)
normalize_result(filtered_cities)
end
private
attr_reader :points
def group_points
points.group_by(&:country)
end
def map_with_cities(grouped_records)
grouped_records.transform_values do |grouped_points|
grouped_points
.pluck(:city, :timestamp) # Extract city and timestamp
.delete_if { _1.first.nil? } # Remove records without city
.group_by { |city, _| city }
.transform_values do |cities|
{
points: cities.count,
timestamp: cities.map(&:last).max # Get the maximum timestamp
}
end
end
end
def filter_cities(mapped_with_cities)
# In future, we would want to remove cities where user spent less than
# 1 hour per day
# Remove cities with less than MINIMUM_POINTS_IN_CITY
mapped_with_cities.transform_values do |cities|
cities.reject { |_, data| data[:points] < MINIMUM_POINTS_IN_CITY }
end
end
def normalize_result(hash)
hash.map do |country, cities|
{
country:,
cities: cities.map { |city, data| { city:, points: data[:points], timestamp: data[:timestamp] } }
}
end
end
end