9

我需要处理像/: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}.

我想出了两个kludges:

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

需要第二:slug => /[^\/]+/个 in 以防止 Rails 认为.bina.b是格式扩展。

有没有办法让 Rails 表现得明智并检查解码:slug后的约束,还是我必须放松约束或手动完成?

4

1 回答 1

0

您可以使用 lambda 作为约束,这样可以更改编码(来自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
于 2013-11-01T14:33:53.740 回答