In routes.rb, I'd like to use Russian characters:
map.connect 'öÃÂÃÂýðû/:id', :controller => 'blog'
Unfortunately, Rails won't recognize it (throwing a routing error), because it compares string "öÃÂÃÂýðû" against URL-encoded string "%D0%B6%D1%83%D1%80%D0%BD%D0%B0%D0%BB". A quick solution is to write:
map.connect "#{CGI.escape('öÃÂÃÂýðû')}/:id", :controller => 'blog'
Or, even better, redefine ActionController::Routing::StaticSegment.initialize method in source:trunk/actionpack/lib/action_controller/routing.rb (so we don't have to write the escape code for each static component of each route):
def initialize(value = nil)
super()
self.value = CGI.escape(value)
end
However, it's not a complete solution, because it doesn't support regexps. For example, this route definition for alphabetical index won't work:
map.connect 'ÃÂúð÷ðÃÂõûÃÂ/:letter',
:controller => 'index',
:requirements => { :letter => /[ðñòóôõÃÂö÷øùúûüýþÿÃÂÃÂÃÂÃÂÃÂÃÂ
ÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂ]/ }
Instead, we need to write something ugly, obfuscated and non-universal like:
map.connect "#{CGI.escape('ÃÂúð÷ðÃÂõûÃÂ')}/:letter",
:controller => 'index',
:requirements => { :letter => Regexp.new( '(%s)' % 'ðñòóôõÃÂö÷øùúûüýþÿÃÂÃÂÃÂÃÂÃÂÃÂ
ÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂÃÂ'.split('').map{|l| CGI.escape(l)}.join('|') )}
Obviously, rather than CGI.escape static segments and regexps (the latter task being pretty non-trivial in general case), it's better to CGI.unescape the URL before matching routes. This is exactly what needs to be done. Unfortunately, I'm not familiar enough with the Rails source code to fix it myself.
(If you're going to test these examples, don't forget to define $KCODE='UTF-8' in config/environment.rb .)