自嵌套轨道类别

时间:2014-07-22 13:01:39

标签: ruby-on-rails ruby ruby-on-rails-3 routing friendly-id

我有一个商店应用程序,我需要制作自定义路由系统,其中URL存储产品的类别。例如,http://example.com/languages/ruby/rails将显示类别#show named' rails',其父级名为' ruby​​',其父级名为' languages'和http://example.com/languages/ruby/rails/store的网址将显示此类别中的产品 目前我有:
category.rb

belongs_to :parent, class_name: 'Category'
has_many :categories, foreign_key: :parent_id
has_many :products

的routes.rb

resources :categories, :path => '', :only => [:index, :show] do
  resources :products, :path => '', :only => [:show]
end
root :to => 'products#index'

但它仍然叠加到2,例如网址http://example.comhttp://example.com/languages显示了类别/子类别列表,但http://example.com/languages/ruby参数{"action"=>"show", "controller"=>"products", "category_id"=>"language", "id"=>"ruby"}
从路由中删除产品根本没有用处 - 然后它只是说No route matches [GET] "/language/ruby",虽然我认为如果当前URL指向类别或产品,可能需要额外检查。
我还尝试了get '*categories/:id', to: 'category#show'种变体 +我使用的是friendly_id gem,因此路径看起来不像http://example.com/2/54/111/6
我只是想知道在这种情况下什么是最好的ruby on rails解决方案,当你需要搜索引擎优化+无穷无尽时(例如无法定义这种递归有多深)嵌套自己的嵌套资源(包括事实, category / language / category / ruby​​ / category / rails看起来很难看。

注意:我使用的大多数信息都来自Stack Overflow和railscasts.com(包括专业/修改过的剧集),所以提到这样的信息的好来源也会很棒。

1 个答案:

答案 0 :(得分:0)

我最近使用最近在Rails上构建的CMS解决了这个问题。我基本上是在运行时从数据库记录中动态构造路由。我写了关于策略的博客文章:

http://codeconnoisseur.org/ramblings/creating-dynamic-routes-at-runtime-in-rails-4

解决方案的核心(调整上面的博客文章)只是迭代数据库记录并构建每个类别所需的路由。这是这样做的主要类:

class DynamicRouter
  def self.load
    Website::Application.routes.draw do

      Category.all.each do |cat|
        get cat.route, 
          to: "categories#show", 
          defaults: { id: cat.id }, 
          as: "#{cat.routeable_name}_#{cat.name}"
      end
    end
  end

  def self.reload
    Website::Application.routes_reloader.reload!
  end
end

对于上述情况,Category模型应该实现" routeable_name"这个方法简单地给出了一个类别名称的下划线版本,该类别名称唯一地命名了该类别的路线(它不是绝对必要的,但在执行" rake路线和#34;看看你有什么时有帮助)。并且#route方法构造到该类别的完整路由。请注意默认值,用于设置类别的ID参数。这使控制器操作非常简单地查找类别的ID字段,如下所示:

class CategoryController < ApplicationController
  def show
    @category = Category.find(params[:id])
  end
end
相关问题