Calmon
Calmon

Reputation: 603

Rails routes.rb - Matching case insensitive

Urls are (for an unclear reason, generate different problems/no real advantage) defined case sensitive by w3.

What are my possibilities in routes.rb match case insensitively?

here the matching:

match '/:foo/library/:bar' => 'library#show'

Url Example: /europe/library/page4711

calls show action in library controller with { :foo => "europe", :bar => "page4711" }

What I want are 2 things:

How do I do this in routes.rb?

Thanks!

Upvotes: 6

Views: 2695

Answers (3)

rdaniels
rdaniels

Reputation: 979

Just add this to your Gemfile

gem 'route_downcaser'

restart rails, no configuration needed. the github for this project is at:

https://github.com/carstengehling/route_downcaser

As noted in the gem "Querystring parameters and asset paths are not changed in any way."

Upvotes: 3

Calmon
Calmon

Reputation: 603

Ok, to answer my own question:

There is no good way to do this within Rails routes.rb.

Here what I did:

For the first thing I created a before_filter in my controller:

before_filter :foo_to_lower_case

def foo_to_lower_case
  params[:foo] = params[:foo].downcase
end

For the second one I created a load balancer rule to get it lowercase to the rails app. Of course you can define a nginx/apache rule as well instead.

Edit: I found another solution for the second part because I disliked the pre-parsing/replacing of every url.

I made "library" to a symbol and wrote a constrained for it which only accept any form of the word "library".

So the line in routes.rb looks like:

match '/:foo/:library/:bar' => 'library#show', :constraints => { :library => /library/i }

Upvotes: 7

Kelvin
Kelvin

Reputation: 20857

To downcase the path, you could set up an initializer to add a Rack middleware. Here I'm checking whether the path begins with /posts and posts isn't part of a longer word. See the code comments for more info.

class PathModifier
  def initialize(app)
    @app = app
  end

  def call(env)
    if env['PATH_INFO'] =~ /^\/posts\b/i
      Rails.logger.debug("modifying path")
      %w(PATH_INFO REQUEST_URI REQUEST_PATH ORIGINAL_FULLPATH).each do |header_name|
        # This naively downcases the entire String. You may want to split it and downcase
        # selectively. REQUEST_URI has the full url, so be careful with modifying it.
        env[header_name].downcase!
      end
    end
    @app.call(env)
  end
end
Rails.configuration.middleware.insert(0, PathModifier)

Upvotes: 2

Related Questions