Class: Routes::Analyzer::RouteUsageTracker

Inherits:
Object
  • Object
show all
Defined in:
lib/routes/analyzer/route_usage_tracker.rb

Instance Method Summary collapse

Constructor Details

#initialize(configuration) ⇒ RouteUsageTracker

Returns a new instance of RouteUsageTracker.



4
5
6
7
# File 'lib/routes/analyzer/route_usage_tracker.rb', line 4

def initialize(configuration)
  @configuration = configuration
  @redis = configuration.redis_client
end

Instance Method Details

#get_all_defined_actionsObject



39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# File 'lib/routes/analyzer/route_usage_tracker.rb', line 39

def get_all_defined_actions
  return [] unless defined?(Rails) && Rails.application

  actions = []
  Rails.application.routes.routes.each do |route|
    next unless route.defaults[:controller] && route.defaults[:action]

    actions << {
      controller: route.defaults[:controller],
      action: route.defaults[:action],
      method: route.verb,
      route: route.path.spec.to_s.gsub(/\(\.:format\)$/, ""),
      name: route.name
    }
  end

  # Remove duplicates based on controller#action (not method-specific)
  actions.uniq { |a| "#{a[:controller]}##{a[:action]}" }
end

#get_usage_statsObject



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/routes/analyzer/route_usage_tracker.rb', line 9

def get_usage_stats
  cutoff_time = @configuration.timeframe.days.ago.to_i

  # Get all controller#action keys
  pattern = "#{@configuration.redis_key_prefix}:*"
  keys = @redis.keys(pattern)

  usage_stats = []

  keys.each do |key|
    route_data = @redis.hgetall(key)
    next if route_data.empty?

    # Filter by timeframe if last_accessed is available
    last_accessed = route_data["last_accessed"]&.to_i
    next if last_accessed && last_accessed < cutoff_time

    usage_stats << {
      controller: route_data["controller"],
      action: route_data["action"],
      method: route_data["method"],
      count: route_data["count"]&.to_i || 0,
      last_accessed: last_accessed ? Time.at(last_accessed) : nil
    }
  end

  # Sort by count (descending)
  usage_stats.sort_by { |stat| -stat[:count] }
end

#merge_with_defined_actions(usage_stats) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
# File 'lib/routes/analyzer/route_usage_tracker.rb', line 59

def merge_with_defined_actions(usage_stats)
  defined_actions = get_all_defined_actions
  usage_by_action = usage_stats.index_by { |stat| "#{stat[:controller]}##{stat[:action]}" }

  merged_actions = []

  defined_actions.each do |defined_action|
    action_key = "#{defined_action[:controller]}##{defined_action[:action]}"
    usage_stat = usage_by_action[action_key]

    if usage_stat
      merged_actions << defined_action.merge(usage_stat)
    else
      merged_actions << defined_action.merge(
        count: 0,
        last_accessed: nil
      )
    end
  end

  # Add any tracked actions that aren't in the defined actions (in case of dynamic actions)
  usage_stats.each do |usage_stat|
    action_key = "#{usage_stat[:controller]}##{usage_stat[:action]}"
    unless defined_actions.any? { |da| "#{da[:controller]}##{da[:action]}" == action_key }
      merged_actions << usage_stat.merge(
        route: nil,
        name: nil
      )
    end
  end

  # Sort by count (descending), then by controller#action name
  merged_actions.sort_by { |action| [ -action[:count], "#{action[:controller]}##{action[:action]}" ] }
end