Ограничения маршрутизации 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