SmartUrlHelper - configurable replacement for url_for. See http://lostechies.com/joshuaflanagan/2012/03/27/a-smarter-rails-url_for-helper/

  • Download Gist
example_config_initializer_smart_urls.rb
Ruby
1 2 3 4 5 6 7 8 9 10
SmartUrlHelper.configure do |url|
url.for ->model{ model.is_a?(Comment) } do |helpers, model|
helpers.post_comment_path(model.post, model)
end
 
# TODO: Add a convenience method for matching on type:
# url.for(Comment) do |helpers, model|
# helpers.post_comment_path(model.post, model)
# end
end
smart_url_helper.rb
Ruby
1 2 3 4 5 6 7 8 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 38 39 40 41 42 43 44 45
module SmartUrlHelper
# A smarter replacement for #url_for. First checks to see if a
# special-case handler has been registered for the given model. If so,
# use that to generate the URL. If not, fall back to Rails' #url_for helper.
# Special-case handlers should be registered in a config/initializer that
# calls SmartUrlHelper.configure.
#
# Returns the default URL for the given model.
def smart_url_for(model, *args)
url = ::SmartUrlHelper::SmartUrlConfiguration.lookup_smart_url(self, model, *args)
return url if url.present?
url_for(model, *args)
end
 
# Call in config/initializer to register model handlers.
# Takes a block for an instance of SmartUlrConfiguration.
def self.configure
Rails.application.config.smart_url_handlers = []
yield ::SmartUrlHelper::SmartUrlConfiguration.new
end
 
# Provides the DSL for registering model handlers in SmartUrlHelper.configure
class SmartUrlConfiguration
# Registers a handler to generate a URL for a model that matches the predicate
#
# predicate - A lambda that takes in a model instance and returns true
# if the handler can generate a URL for the given model.
# url_generator - A block that builds a url for the given model.
# The block will receive a helper object and the model
# as parameters.
def for(predicate, &url_generator)
self.class.handlers << [predicate, url_generator]
end
 
def self.handlers
Rails.application.config.smart_url_handlers
end
 
def self.lookup_smart_url(context, model, *args)
handler = self.handlers.detect{|h| h[0].call(model)}
return nil unless handler.present?
handler[1].call(context, model)
end
end
end

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.