class RailsRoutesAnalyzer::RouteIssue::Resources

Constants

ONLY_EXCEPT_PARAM_REGEX
RESOURCES_PARSE_REGEX

This is horrible but just maybe works well enough most of the time to be useful.

RESOURCE_OTHER_PARAM_REGEX

Public Class Methods

does_params_look_like_a_safe_hash?(params) click to toggle source

Check if the parameter string contains only a limited set of known resource hash keys in which case it should generally be safe to append only:/except: to it.

# File lib/rails_routes_analyzer/route_issue/resources.rb, line 118
def self.does_params_look_like_a_safe_hash?(params)
  return false if params =~ /[{}]/ # definitely can't handle: "resources :name, { key: val }"

  # Replace all known "key: simple_value" pairs with 'X'
  result = params.gsub(RESOURCE_OTHER_PARAM_REGEX, 'X')

  # Remove all whitespace
  result.gsub!(/\s/, '')

  # check that the result string looks like: "X" or "X,X", "X,X,X" depending on how many parameters there were
  result.split(',').uniq == %w(X)
end
try_to_fix_resources_line(line, suggestion) click to toggle source
# File lib/rails_routes_analyzer/route_issue/resources.rb, line 85
def self.try_to_fix_resources_line(line, suggestion)
  data = line.match(RESOURCES_PARSE_REGEX)
  line_break = line[/$(.*)\z/m, 1]

  return unless data

  separator = data[:separator].presence || ', '

  params = \
    if [nil, ''].include?(data[:params])
      suggestion
    elsif (existing = data[:params][ONLY_EXCEPT_PARAM_REGEX]).present?
      # We get here if the only/except parameter already exists and
      # our only task is to replace it, should generally be ok.
      data[:params].sub(existing, suggestion)
    elsif does_params_look_like_a_safe_hash?(data[:params])
      # If params looks like a hash it should be safe to append the suggestion
      "#{data[:params]}, #{suggestion}"
    elsif (match = data[:params].match(/\A(?<opening>\s*{\s*)(?<inner_data>.*?)(?<closing>\s*}\s*)\z/))
      # If params looks like a safe hash between { and } then add they key inside the hash
      if does_params_look_like_a_safe_hash?(match[:inner_data])
        "#{match[:opening]}#{match[:inner_data]}, #{suggestion}#{match[:closing]}"
      end
    end

  return unless params

  "#{data[:beginning]}#{separator}#{params}#{data[:end]}#{line_break}"
end

Public Instance Methods

error_suggestion(num_controllers:, **) click to toggle source
# File lib/rails_routes_analyzer/route_issue/resources.rb, line 14
def error_suggestion(num_controllers:, **)
  "use #{suggested_param}".tap do |message|
    message << " only for #{controller_class_name}" if num_controllers > 1
  end
end
human_readable_error_message() click to toggle source
# File lib/rails_routes_analyzer/route_issue/resources.rb, line 10
def human_readable_error_message
  "`#{route_creation_method}' call at #{file_location} for #{controller_class_name} should use #{suggested_param}"
end
try_to_fix_line(line, suggestion: suggested_param) click to toggle source
# File lib/rails_routes_analyzer/route_issue/resources.rb, line 81
def try_to_fix_line(line, suggestion: suggested_param)
  self.class.try_to_fix_resources_line(line, suggestion)
end
verbose_message() click to toggle source
# File lib/rails_routes_analyzer/route_issue/resources.rb, line 20
def verbose_message
  "This route currently covers unimplemented actions: #{format_actions(missing_actions.sort)}"
end