【问题标题】:How do I re-write this route to be shorter?我如何重写这条路线更短?
【发布时间】:2013-03-29 20:03:30
【问题描述】:

我的routes.rb 中有resources :tags

所以当我转到/tags/ios 时,它会显示正确的Tag#Show 视图。

我想要发生的是当用户转到/tags/ios时,它显示为/ios,同样我希望生成的路径始终为/ios(并且没有前导/tags)。

这是我如何在each 块中呈现该链接的示例:

<%= link_to "#{tag.name}", url_for(tag) %>

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 routes


    【解决方案1】:

    在你的 routes.rb 中

    resources :tags
    match '/:tag_name' => 'tags#show'
    

    然后在您的 tags_controller#show 操作中,您可以通过以下方式访问标签名称:

    params[:tag_name]
    

    请务必将其放在路线文件的末尾,因为它会捕获所有内容。此外,由于它会捕获所有内容,因此如果它不是有效的标签名称,您应该呈现 404:

    def show
        unless @tag = Tag.where(name: params[:tag_name]).first
            raise ActionController::RoutingError.new('Not Found')
        end
    end
    

    将 /tags/ruby 重定向到 /ruby:

    match "/tags/:tag_name" => redirect("/%{tag_name}")
    

    http://guides.rubyonrails.org/routing.html

    【讨论】:

    • 当我在这样的 URL 上时:http://localhost:3000/tags/ruby-on-rails,这就是参数的样子:Request parameters {"action"=&gt;"show", "controller"=&gt;"tags", "id"=&gt;"ruby-on-rails"}
    • 如果你想让它匹配,那么只需使用match '/:id' =&gt; 'tags#show'
    • 好的....完美...所以现在/tags/ruby-on-rails/ruby-on-rails 位于同一个地方。但是……每个链接中生成的路径还是/tags/ruby-on-rails。另外...如果用户转到/tags/ruby,我希望地址栏中的URL 读取/ruby。所以我不只是想要一个匹配,而是基本上重写一个 URL,并且在生成的 url_for 路径中也是如此。
    • 用重定向部分更新了答案。不确定如何让link_to @tag 在我的脑海中正常工作。在此处为该部分再发一篇文章。
    • 我什至尝试过match "/tags/:id" =&gt; redirect("/%{id}"),但这不起作用。我实际上并不是在寻找官方的redirect。更像是路由掩码或类似的东西。
    【解决方案2】:

    这里的问题是命名空间

    如果你定义一个类似的路线

    get "/(:slug)" => "Tags#show"

    这基本上会匹配任何有效标签或无效标签。我会这样做的方式是

    在您的路线文件中:

      begin  
        Tag.all.each do |t|
          begin
            get "#{t.slug}" => "Tags#show"
          rescue
          end
        end
      rescue
      end
    

    然后在你的标签控制器中你可以

     def show
        slug = request.env['PATH_INFO']
        @tag = Tag.find_by_slug(slug)
      end
    

    我的回答来自我写的另一个你可能感兴趣的回答How to create app-wide slug routing for Rails app?

    【讨论】:

    • 我没有使用蛞蝓。只是Tagname 属性。
    • 这是一个很好的方法。不过,所有rescues 是怎么回事……你不相信自己的代码吗?
    • 这似乎有点笨拙且效率低下,不是吗?对于每个请求,我都会发送Tag.all.each。就我而言,我有 1300 多个标签,所以我可以看到它非常丑陋,非常快 - 还是我错过了什么?
    • 在生产中,由于没有更好的词,路线被编译。这只会在您启动服务器时发生一次。
    • 你可能可以删除救援,从某种意义上说我不相信我自己的代码。例如,当您出于某种原因运行 rake 时会加载路由,因此 rake db:migrate 在首次部署到新服务器时可能会失败,因为 t.slug 并且标记表将不存在
    【解决方案3】:

    因此,尽管我从这些人那里得到了很多很好的建议,但我还是找到了我认为最适合我的解决方案。

    我要做的基本上是在所有标签链接的实际 URL 和 URL 栏中将 /tags/ruby 呈现为 /ruby

    我不想做任何会给我的应用增加负载的事情。

    这是适合我的解决方案:

    resources :tags, path: "", except: [:index, :new, :create]
    

    使用path:,您可以指定要显示的路径。即你想在你的资源之前出现什么。因此,如果您希望您的 URL 看起来像 myhotness/tags/ruby,那么您只需使用 path: "myhotness"

    我不想在我的路径中有任何东西,所以我把它留空了。

    对于它的价值,您甚至可以为该路由添加一个约束,如下所示:

    resources :tags, path: "", except: [:index, :new, :create], constraints: { :id => /.*/ }
    

    【讨论】:

      猜你喜欢
      • 2015-03-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-30
      • 2015-09-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多