Created
March 28, 2012 02:58
-
-
Save joshuaflanagan/2223161 to your computer and use it in GitHub Desktop.
SmartUrlHelper - configurable replacement for url_for. See http://lostechies.com/joshuaflanagan/2012/03/27/a-smarter-rails-url_for-helper/
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment