Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
identify routes defined by hashes that are not declared in routes.rb
desc 'identify routes defined by hashes that are not declared in routes.rb'
task :missing_routes => :environment do
file_paths = FileList[
"#{Rails.root}/app/helpers/**/*.rb",
"#{Rails.root}/app/views/**/*.html.erb"
]
file_paths.each do |file_path|
errors = []
File.read(file_path).scan(url_hash_regex) do |match|
hash = sanitize($&).merge({only_path: true})
begin
Rails.application.routes.url_for(hash)
rescue => e
errors << e.message
end
end
print_errors(file_path, errors) if errors.size > 0
end
end
def print_errors path, errors
puts path
puts "=" * path.length
errors.each do |e|
puts e
end
puts "\n\n"
end
def sanitize string
string
.split(',')
.map do |pair|
resolve_key_and_value pair do |match|
create_hash_from match
end
end
.reduce(:merge)
end
def resolve_key_and_value pair, &block
HashMatcher
.new(value: :no_quotes)
.expression
.match(pair) do |match|
yield match
end
end
def create_hash_from match
return match[1].present? ?
{ match[1] => fake_value(match[2]) } :
{ match[3] => fake_value(match[4]) }
end
def fake_value value
value =~ /^@|\.|\[|\(/ ? "faked" : value
end
def url_hash_regex
action_controller_pair = HashMatcher
.new(key: /action|controller/)
.expression
generic_pair = HashMatcher
.new
.expression
/(#{action_controller_pair})(?:,\s*(#{generic_pair}))*/
end
class HashMatcher
attr_accessor :expression
attr_reader :key, :value
VALUE_WITH_QUOTES = /([\w:'"\.\/@\(\)\[\]-]*)/
VALUE_WITHOUT_QUOTES = /['":]?([\w\.\/@\(\)\[\]-]*)['"]?/
def initialize opts={}
@key = opts[:key] || /[\w]*/
@value = if opts[:value] == :no_quotes
VALUE_WITHOUT_QUOTES
else
opts[:value] || VALUE_WITH_QUOTES
end
@expression = /#{hash_rocket}|#{ruby_1_9}/
end
def hash_rocket
/:(#{key})\s*=>\s#{value}/
end
def ruby_1_9
/(#{key}):\s#{value}/
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment