Rails 路线 - 如何使它们不区分大小写?

发布于 2024-08-22 06:20:38 字数 634 浏览 6 评论 0原文

Ruby on Rails 中的路由区分大小写。好像之前有人提出过这个问题,而且已经标记为无法解决。

http://rails.lighthouseapp.com/projects/8994 /tickets/393-routes-are-case-sensitive

这让我感到不幸,因为我并没有真正看到我自己的应用程序对区分大小写的路线有任何好处,而缺点是它创造了潜在的风险在我看来,这是因为混乱和缺乏修饰的总体外观。

使我的路线不区分大小写的最佳方法是什么?

我在 Google 搜索中发现了这个提示:

map.connect "web_feeds/:action", :controller  => 'web_feeds', :action => /[a-z_]+/i

这很聪明,但它仍然使 url 的 web_feeds 部分区分大小写。然而,如果不手动输入 wEb_feEds 的每种可能的组合,我没有看到任何类似的解决方案,但这显然是一个可怕的解决方案,原因有很多。

Routes in Ruby on Rails are case sensitive. It seems someone brought this up before, and it has been labeled will not fix.

http://rails.lighthouseapp.com/projects/8994/tickets/393-routes-are-case-sensitive

That strikes me as unfortunate, as I don't really see any upside on my own application for routes to be case sensitive, while on the downside it creates a potential for confusion and a general appearance of lack of polish in my opinion.

What's the best way to make my routes case insensitive?

I found this tip on a Google search:

map.connect "web_feeds/:action", :controller  => 'web_feeds', :action => /[a-z_]+/i

This is clever, but it still leaves the web_feeds portion of the url case sensitive. I don't see any similar way around this, however, without entering in each possible combination of wEb_feEds manually, but that is obviously a horrible solution for any number of reasons.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

╭⌒浅淡时光〆 2024-08-29 06:20:38

Rails 中的路由区分大小写,因为 URL 区分大小写。来自W3C

URL 通常区分大小写
(机器名称除外)。
可能有 URL 或 URL 的一部分,
大小写并不重要,但是
识别这些可能并不容易。
用户应始终考虑 URL
区分大小写。

Routes in Rails are case sensitive because URLs are case sensitive. From the W3C:

URLs in general are case-sensitive
(with the exception of machine names).
There may be URLs, or parts of URLs,
where case doesn't matter, but
identifying these may not be easy.
Users should always consider that URLs
are case-sensitive.

掩饰不了的爱 2024-08-29 06:20:38

我刚刚遇到了同样的问题,并使用中间件解决了它 - 看看这里:

http://gehling.dk/2010/02/how-to-make-rails-routing-case-insensitive/

注意:这仅适用于 Rails 2.3+

  • Carsten

I've just has the same problem, and solved it using middleware - have a look here:

http://gehling.dk/2010/02/how-to-make-rails-routing-case-insensitive/

Note: This only applies for Rails 2.3+

  • Carsten
稳稳的幸福 2024-08-29 06:20:38

好吧,你可以尝试另一种方法。使 case 转换服务器端并将所有内容发送到 Rails Downcase。

我认为你可以通过 mod_rewrite 或 mod_spelling 来实现这一点。

Well you could try another approach. Make the case transform serverside and send everything to rails downcase.

I think you can achieve this with either mod_rewrite or mod_spelling.

人生戏 2024-08-29 06:20:38

一个简单的解决方案是,可能不是一种优雅的方式,但可行的是:
像这样在应用程序控制器中使用 before_filter 。

  before_filter :validate_case

  def validate_case
    if request.url != request.url.downcase
      redirect_301_permanent_to request.url.downcase
    end
  end

  def redirect_301_permanent_to(url)
     redirect_to url, :status=>:moved_permanently 
  end

正如我已经说过的,它不是一个优雅但可行的方法,所以请不要投反对票。 :P

A simple solution is, may be not an elegant way, but yet workable is:
Use a before_filter in your application controller like this.

  before_filter :validate_case

  def validate_case
    if request.url != request.url.downcase
      redirect_301_permanent_to request.url.downcase
    end
  end

  def redirect_301_permanent_to(url)
     redirect_to url, :status=>:moved_permanently 
  end

As i already told that its not an elegant but yet workable, so no down votes please. :P

蓝眸 2024-08-29 06:20:38

只需将其修补为默认小写即可。简单的例子:

module ActionController
  module Caching
    module Pages
      def cache_page(content = nil, options = nil)
        return unless perform_caching && caching_allowed

        path = case options
          when Hash
            url_for(options.merge(:only_path => true, :skip_relative_url_root => true, :format => params[:format]))
          when String
            options
          else
            request.path
        end

        path = path.downcase

        self.class.cache_page(content || response.body, path)
      end
    end
  end
end

just monkey-patch it to downcase by default. simple example:

module ActionController
  module Caching
    module Pages
      def cache_page(content = nil, options = nil)
        return unless perform_caching && caching_allowed

        path = case options
          when Hash
            url_for(options.merge(:only_path => true, :skip_relative_url_root => true, :format => params[:format]))
          when String
            options
          else
            request.path
        end

        path = path.downcase

        self.class.cache_page(content || response.body, path)
      end
    end
  end
end
缱倦旧时光 2024-08-29 06:20:38

尽管 URL 区分大小写,但如果您想让路由不区分大小写,则可以使用一种肮脏的 hack 方法。

在 application_controller.rb 中输入:

rescue_from ActionController::RoutingError do |exception|
 redirect_to request.url.downcase
end

但实际上不要这样做。您为任何不存在的路由创建重定向循环。您确实应该将 request.request_uri 解析为其组件,将它们小写,并使用它们生成您重定向到的合法路由。正如我刚才提到的,这是一个肮脏的黑客行为。然而,我认为这比让你的路线图变得丑陋和黑客要好。

Though URLs are case-sensitive, if you want to make your routes case-insensitive, there is a dirty hack you can do.

In application_controller.rb put:

rescue_from ActionController::RoutingError do |exception|
 redirect_to request.url.downcase
end

But don't actually do that. You create a redirect loop for any non-existant routes. You really should parse request.request_uri into its components, downcase them, and use them to generate the legit route that you redirect to. As I mentioned right off, this is a dirty hack. However, I think this is better than making your route map ugly and hackish.

苯莒 2024-08-29 06:20:38

(几年后发布)

如果您只寻找不区分大小写的特定路线,就像我的情况一样,我最终做的是以下内容。

假设您的路线是

  get "items/:id" => "item#show"

这将解析 /item/123 但不会解析 /ITEM/123Item/123

您可以使用分段约束,将 item 视为参数,并添加默认值,这样您的路线助手就不需要指定它(因此保持上面原始路线的样子)

  get ":item/:id", constraints: { item: /item/i }, defaults: { item: "item" }  => "item#show"

:你在 /item 下有多个路由,你可以用一个范围来概括这个概念:

scope ":item/", constraints: { item: /item/i }, defaults: { item: "item" } do
  get "/:id" => "item#show"
  delete "/:id" => "item#destroy"
end

(Posting this years later)

If you are looking only for specific routes to be case insensitive, like it was in my case, what I ended up doing is the following.

Say your route is

  get "items/:id" => "item#show"

This will resolve /item/123 but not /ITEM/123 nor Item/123.

You can use a segment constraint, treat item as a param, and add a default so your routes helpers don't need to specify it (hence remain what they would be with the original route above):

  get ":item/:id", constraints: { item: /item/i }, defaults: { item: "item" }  => "item#show"

If you have multiple routes under /item, you can generalise this concept with a scope:

scope ":item/", constraints: { item: /item/i }, defaults: { item: "item" } do
  get "/:id" => "item#show"
  delete "/:id" => "item#destroy"
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文