views:

48

answers:

1

I have the following route in routes.rb:

map.resources 'protégés', :controller => 'Proteges', :only => [:index]
#
# this version doesn't work any better:
# map.resources 'proteges', :as => 'protégés', :only => [:index]

When I go to "http://localhost:3000/protégés" I get the following:

No route matches "/prot%C3%A9g%C3%A9s" with {:method=>:get}

I figured that the HTTP server I was using (Mongrel) wasn't unescaping properly. I also tried Apache with Passenger to no avail. I tried adding a Rack middleware:

require 'cgi'

class UtfUrlMiddleware

  def initialize(app)
    @app = app
  end

  def call(env)
    request = Rack::Request.new(env)
    puts "before: #{request.path_info}"
    if request.path_info =~ /%[0-9a-fA-F]/
      request.path_info = CGI.unescape(request.path_info)
    end
    puts "after:  #{request.path_info}"
    @app.call(env)
  end

end

I see the correct information in the logs:

before: /prot%C3%A9g%C3%A9s
after:  /protégés

but I still see the same "No route matches" error.

How do I convince Rails to use the internationalized route? I'm on Rails 2.3.5 for what it's worth.

+1  A: 

The problem is that Rails uses the "REQUEST_URI" environment variable. Thus, the following works:

# in UtfUrlMiddleware:
def call(env)
  if env['REQUEST_URI'] =~ /%[0-9a-fA-F]/
    env['REQUEST_URI'] = CGI.unescape(env['REQUEST_URI'])
  end
  @app.call(env)
end
James A. Rosen