Makes routing in Rails case-insensitive
Ruby HTML CSS JavaScript
Failed to load latest commit information.
lib
test
.gitignore
.travis.yml
Gemfile
MIT-LICENSE
README.rdoc
Rakefile
route_downcaser.gemspec

README.rdoc

RouteDowncaser

Note about Rails 5.0.0: Rails 5.0.0.beta1 was released on December 18th. RouteDowncaser 1.1.5 has been tested to work with this beta-version of Rails.

Makes routing in Rails case-insensitive (and other Rack-servers like Sinatra)

This gem hooks into the Rack middleware of Rails. This way all paths are downcased before dispatching to Rails' routing mechanism. Querystring parameters and asset paths are not changed in any way.

Requirements

This gem has been tested with Rails 3.1.x, 4.0.x, 4.1.x, 4.2.x. It reportedly also works with Sinata, although I do not use Sinatra myself. Sinatra test-cases will be most welcome.

If you want this functionality in a Rails 2.x-3.0 application, please refer to this blog post.

Note: from version 1.2.0, route_downcaser depends on ActiveSupport 3.2 or later. This was necessary to enable support for multibyte characters.

Installing

Rails

Just add the gem to your gemfile and run bundle

gem 'route_downcaser'

Then restart your Rails server. No configuration is needed. The gem simply hooks itself into the Rack middleware call stack.

If you have a controller named app/controllers/foo_controller.rb and the action index, you can now call it with:

http://localhost:3000/foo
http://localhost:3000/Foo
http://localhost:3000/FOO
http://localhost:3000/foo/index
http://localhost:3000/Foo/INDEX
http://localhost:3000/FOO/IndeX

All the above are valid.

Sinatra

In your Gemfile you add the gem:

gem 'route_downcaser'

In your application.rb you add the following (after loading Sinatra)

require 'route_downcaser'
use RouteDowncaser::DowncaseRouteMiddleware

Now this statement

get '/foo' do
  "Hello"
end

will respond to all these requests:

http://localhost:4567/foo
http://localhost:4567/Foo
http://localhost:4567/FOO

Configuration Options

Configuration options can be set using an initializer in your application like so:

# config/initializers/route_downcaser.rb

RouteDowncaser.configuration do |config|
  config.redirect = true

  config.exclude_patterns = [
    /assets\//i,
    /fonts\//i,
    /some\/important\/path/i
  ]
end

redirect

With this configuration option set to `true`, the middleware will 301 redirect all routes to their downcased version. Example: `localhost:3000/Foo` will redirect to `localhost:3000/foo`.

exclude_patterns

Array of regular expressions. If the requested path matches one of these expressions, RouteDowncaser will not change anything.

Background information

Sometimes you may wish to market a url which contains a controller name - like www.myshop.com/specialoffer. If this is done on offline media it will cause potential customers trouble, if they don't use the correct casing. If, for some reason, the user types www.myshop.com/Specialoffer (with capital S), your Rails app will return a 404 not found.

The strange thing is, that the W3C specification states:

URLs in general are case-sensitive (with the exception of machine names). There may be URLs, or parts of URLs, where case doesn't matter, but identifying these may not be easy. Users should always consider that URLs are case-sensitive.

So www.myshop.com is case-insensitive and can be written as WWW.MYSHOP.COM, but the path (/specialoffer) is not.

It may make perfect sense for the W3C guys, but not for the average user.

When Rails introduced Rack middleware, it suddenly became possible to hook into the call-stack before the URL is used for action dispatching.

At first I just made this code as a snippet and published it on my blog. But since I found out that many people are actually using this, I finally decided to convert it into a gem.

All it really does is to take the path and downcase it before dispatching. Querystring parameters are NOT touched, they keep their casing, since it may have some contextual meaning.

Changelog

1.2.0

Support for multibyte characters - dependency on ActiveSupport version 3.2 or later

1.1.5

Configuration now namespaced to avoid name clashing with other modules. Thanks goes to tgk for this

1.1.4

Better solution to the incompatibility issue with Warden. Thank you to l3akage

1.1.3

Fixes issue #14. If Devise/Warden is used in the Rails app, RouteDowncaser::DowncaseRouteMiddleware needs to be inserted before Warden::Manager in the middleware list.

1.1.2

POST requests must never result in a redirect, even if the config.redirect is true

More robust test-cases have been added

1.1.1

Fixed issue #17. Thanks go to TkiTDO

1.1.0

Refactored main code and tests for much better structure

1.0.1

Refactored parts of the code to work with Rails 4.2.0

New config for ignoring/excluding paths

0.2.2

Redirection is now possible as a configurable option. Thanks goes to Mike Ackerman

0.2.1

The gem has now been tested to work with Rails 4.0 (it mostly involved changes in the test dummy-app because of deprecations between Rails 3.2 and 4.0)

0.2.0

Asset urls are now ignored - important since filesystems may be case sensitive. Thanks goes to Casey Pugh

0.1.2

Removed silly dependencies (sqlite3, etc.)

0.1.1

Added documentation README

0.1.0

First version of gem

Feedback

This is my first published gem, so bear with me, if I have missed some conventions. If you find anything wrong in documentation, code, dependencies, etc. please let me know at carsten@sarum.dk.

License

MIT License. Copyright 2013 Carsten Gehling. gehling.dk