William Jones
William Jones

Reputation: 18279

Rails Routes - How to make them case insensitive?

Routes in Ruby on Rails are case sensitive. It seems someone brought this up before, and it has been labeled will not fix.

http://rails.lighthouseapp.com/projects/8994/tickets/393-routes-are-case-sensitive

That strikes me as unfortunate, as I don't really see any upside on my own application for routes to be case sensitive, while on the downside it creates a potential for confusion and a general appearance of lack of polish in my opinion.

What's the best way to make my routes case insensitive?

I found this tip on a Google search:

map.connect "web_feeds/:action", :controller  => 'web_feeds', :action => /[a-z_]+/i

This is clever, but it still leaves the web_feeds portion of the url case sensitive. I don't see any similar way around this, however, without entering in each possible combination of wEb_feEds manually, but that is obviously a horrible solution for any number of reasons.

Upvotes: 12

Views: 10380

Answers (7)

lucius
lucius

Reputation: 61

(Posting this years later)

If you are looking only for specific routes to be case insensitive, like it was in my case, what I ended up doing is the following.

Say your route is

  get "items/:id" => "item#show"

This will resolve /item/123 but not /ITEM/123 nor Item/123.

You can use a segment constraint, treat item as a param, and add a default so your routes helpers don't need to specify it (hence remain what they would be with the original route above):

  get ":item/:id", constraints: { item: /item/i }, defaults: { item: "item" }  => "item#show"

If you have multiple routes under /item, you can generalise this concept with a scope:

scope ":item/", constraints: { item: /item/i }, defaults: { item: "item" } do
  get "/:id" => "item#show"
  delete "/:id" => "item#destroy"
end

Upvotes: 0

Carsten Gehling
Carsten Gehling

Reputation: 86

I've just has the same problem, and solved it using middleware - have a look here:

http://gehling.dk/2010/02/how-to-make-rails-routing-case-insensitive/

Note: This only applies for Rails 2.3+

  • Carsten

Upvotes: 7

Nadeem Yasin
Nadeem Yasin

Reputation: 4524

A simple solution is, may be not an elegant way, but yet workable is: Use a before_filter in your application controller like this.

  before_filter :validate_case

  def validate_case
    if request.url != request.url.downcase
      redirect_301_permanent_to request.url.downcase
    end
  end

  def redirect_301_permanent_to(url)
     redirect_to url, :status=>:moved_permanently 
  end

As i already told that its not an elegant but yet workable, so no down votes please. :P

Upvotes: 3

bitemerailsboys
bitemerailsboys

Reputation: 29

just monkey-patch it to downcase by default. simple example:

module ActionController
  module Caching
    module Pages
      def cache_page(content = nil, options = nil)
        return unless perform_caching && caching_allowed

        path = case options
          when Hash
            url_for(options.merge(:only_path => true, :skip_relative_url_root => true, :format => params[:format]))
          when String
            options
          else
            request.path
        end

        path = path.downcase

        self.class.cache_page(content || response.body, path)
      end
    end
  end
end

Upvotes: 2

Dom Brezinski
Dom Brezinski

Reputation: 107

Though URLs are case-sensitive, if you want to make your routes case-insensitive, there is a dirty hack you can do.

In application_controller.rb put:

rescue_from ActionController::RoutingError do |exception|
 redirect_to request.url.downcase
end

But don't actually do that. You create a redirect loop for any non-existant routes. You really should parse request.request_uri into its components, downcase them, and use them to generate the legit route that you redirect to. As I mentioned right off, this is a dirty hack. However, I think this is better than making your route map ugly and hackish.

Upvotes: 0

vise
vise

Reputation: 13373

Well you could try another approach. Make the case transform serverside and send everything to rails downcase.

I think you can achieve this with either mod_rewrite or mod_spelling.

Upvotes: 4

John Topley
John Topley

Reputation: 115292

Routes in Rails are case sensitive because URLs are case sensitive. From the W3C:

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.

Upvotes: 12

Related Questions