Skip to content

Instantly share code, notes, and snippets.

@TooManyBees
Last active August 29, 2015 14:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TooManyBees/40041b44dbc545c7627d to your computer and use it in GitHub Desktop.
Save TooManyBees/40041b44dbc545c7627d to your computer and use it in GitHub Desktop.
Quicker routing helpers for Rails apps
# I hate the fact that Rails.application.routes.url_helpers.whatever
# is so damn slow.
#
# def tt n
# start = Time.now
# n.times { yield }
# Time.now - start
# end
#
# tt(100) { Rails.application.routes.url_helpers.entry_path(edition_id: 'us', id: 12345) }
# => 0.192188
#
# test = (class X; include QuickRoutes; end).new
# tt(100) { test.entry_path(edition_id: 'us', id: 12345) }
# => 0.001878
#
# This isn't needless optimization. Using Rails's native helpers to
# generate links for 100 entries takes at least 100ms even on a box
# faster than my laptop.
module QuickRoutes
@@routes = {}
Rails.application.routes.named_routes.names.each do |sym|
define_method("#{sym}_path") do |params={}|
template = @@routes[sym] ||= get_route_template(sym)
fill_route(template, params)
end
end
def fill_route(template, params)
_params = params.dup
format = _params.delete(:format)
template = template.sub('(.:format)', format ? ".#{format}" : '')
missing = []
# This is probably not a comprehensive gsubbing solution, particularly
# if there are optional params other than format.
base = template.gsub(/:([^:\/.]+)/) do |m|
_params.delete($1.to_sym) { missing << $1 }
end
if missing.length > 0
raise "Missing path params: #{missing.join(', ')}"
end
if _params.count > 0
base + "?" + URI.encode_www_form(_params)
else
base
end
end
def get_route_template(symbol)
route_name = symbol.to_s
route = Rails.application.routes.routes.find { |r| r.name == route_name }
if route
# If this breaks at any point, consult
# rails/actionpack/lib/action_dispatch/routing/inspector.rb
# which is the formatter used to print routes to the console in the
# rake command
route.path.spec.to_s
else
raise "No such route: #{route_name}"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment