Ограничения маршрутизации Rails и UTF-8

Мне нужно обрабатывать маршруты как /:slug, Слизни ограничены в другом месте, чтобы соответствовать:

\A[\p{Alnum}_.-]{3,}\z

Очевидные маршруты:

get '/:slug' => '...', :constraints => { :slug => /[\p{Alnum}_.-]{3,}/ }
get '/:slug' => '...', :slug => /[\p{Alnum}_.-]{3,}/

хорошо работать с ASCII URL-адресами, такими как /mu-is-too-short а также /where.is.pancakes.house но все разваливается, когда URL /µ-is-too-short, Браузер отправляет это на сервер:

/%C2%B5-is-too-short

и Rails пытается проверить закодированный %C2%B5-is-too-short против :slug ограничение и неудача, потому что % это не \p{Alnum},

Я придумал два кладжа:

get '/:slug' => '...', :slug => /.{3,}/
get '/:slug' => '...', :slug => /[^\/]+/, :constraints => lambda { |r| r.path_parameters[:slug].to_s =~ /\A[\p{Alnum}_.-]{3,}\z/ }

:slug => /[^\/]+/ во втором необходимо, чтобы Rails не думал, что .b в a.b это расширение формата.

Есть ли способ заставить Rails вести себя разумно и проверять декодированный :slug против ограничений или я должен ослабить ограничения или сделать это вручную?

1 ответ

Вы можете использовать лямбду для ограничения и таким образом изменить кодировку (с http://www.intridea.com/blog/2011/2/21/use-lambdas-for-rails3-route-constraints):

scope :constraints => lambda{|req| !req.session[:user_id].blank? } do
  # all my logged in routes
end
Другие вопросы по тегам