Module: Woods::Extractors::RouteHelperResolver
- Included in:
- ControllerExtractor, MailerExtractor, PhlexExtractor, ViewComponentExtractor, ViewTemplateExtractor
- Defined in:
- lib/woods/extractors/route_helper_resolver.rb
Overview
Shared module for resolving named route helpers to controller#action targets.
Builds an inverse lookup from ‘Rails.application.routes.named_routes`, mapping route helper names (e.g., “new_post”) to their controller and action. Include this module and call #build_route_helper_map in your initializer.
Constant Summary collapse
- IGNORED_HELPER_PREFIXES =
Route helper prefixes that produce non-navigation dependencies. These generate asset URLs or are common false positives from non-route uses of _path/_url suffixes in Ruby code.
NOTE: ‘root` is intentionally excluded — root_path is the most common Rails route helper, but it appears so frequently in non-navigation contexts (path construction, config, tests) that it generates excessive noise. The tradeoff: “what links to the home page?” won’t appear in graph queries. Add new prefixes here when false positives are discovered in host apps.
%w[ asset image stylesheet javascript font audio video turbo_stream file tmp base root log socket download ].freeze
Instance Method Summary collapse
-
#build_route_helper_map ⇒ Object
Build the route helper lookup map from Rails named routes.
-
#resolve_route_helper(helper_name) ⇒ Hash?
Resolve a _path/_url helper to its controller#action target.
-
#safe_rails_application_routes ⇒ Object
True when Rails.application.routes is reachable.
Instance Method Details
#build_route_helper_map ⇒ Object
Build the route helper lookup map from Rails named routes. Call this once in your extractor’s initialize method.
Resilient to partial test doubles: any exception raised while traversing Rails routes (unstubbed ‘application` on a double, missing `named_routes`, etc.) is swallowed and leaves the map empty — extractors fall back to returning the helper name literal as the dependency target.
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/woods/extractors/route_helper_resolver.rb', line 61 def build_route_helper_map @route_helper_map = {} return unless defined?(Rails) routes = safe_rails_application_routes return unless routes routes.named_routes.each do |name, route| controller = route.defaults[:controller] action = route.defaults[:action] next unless controller && action @route_helper_map[name.to_s] = { controller: "#{controller.camelize}Controller", action: action, path: route.path.spec.to_s.gsub('(.:format)', ''), verb: extract_route_verb(route) } end rescue StandardError # Leave @route_helper_map empty — navigation-edge extractors will # fall back to the helper-name literal. @route_helper_map = {} end |
#resolve_route_helper(helper_name) ⇒ Hash?
Resolve a _path/_url helper to its controller#action target.
106 107 108 109 110 111 |
# File 'lib/woods/extractors/route_helper_resolver.rb', line 106 def resolve_route_helper(helper_name) base = helper_name.sub(/_(path|url)\z/, '') return nil if IGNORED_HELPER_PREFIXES.any? { |prefix| base.start_with?("#{prefix}_") || base == prefix } @route_helper_map&.[](base) end |
#safe_rails_application_routes ⇒ Object
True when Rails.application.routes is reachable. Probing via ‘respond_to?` first so partial RSpec doubles that haven’t stubbed ‘.application` don’t raise MockExpectationError (which descends from Exception, not StandardError — ‘rescue StandardError` would not catch it).
91 92 93 94 95 96 97 98 99 100 |
# File 'lib/woods/extractors/route_helper_resolver.rb', line 91 def safe_rails_application_routes return nil unless Rails.respond_to?(:application) app = Rails.application return nil unless app.respond_to?(:routes) app.routes rescue StandardError nil end |