Rails动态页面的嵌套路由

时间:2016-11-09 09:41:24

标签: ruby-on-rails routing

在我的Rails应用程序中,我有存储在数据库中的页面。

例如:

id: 1
name: 'About'
slug: 'about'
parent_id: null

id: 2
name: 'Team'
slug: 'team'
parent_id: 1

id: 3
name: 'Cameron'
slug: 'cameron'
parent_id: 2

slug用于通过路由访问它们,如下所示:

match '/:slug' => 'pages#show', :via => :get, :as => :page

所以我可以访问这些页面:

/about
/team
/cameron

我想要做的是使用parent_id,以便路由成为:

/about/team/cameron

这可以单独使用路由来实现吗?或者我还需要做其他事情吗?

2 个答案:

答案 0 :(得分:1)

使用嵌套路由无法实现此目的,但您可以使用route globbing and wildcards。让我概述为您实现它可能需要采取的步骤:

  1. 将诸如get '*path', to: 'pages#show'之类的通配符路由添加到路由文件的末尾,否则它将匹配所有其他获取请求。
  2. params['path']操作中获取pages#show的记录。
  3. 从最后一段开始,尝试找到它。如果找不到,则该页面不存在。如果你得到最后一个slug段的结果,看看他们的参数,如果它们与下一个段塞段匹配等等。

    如果它将成为一棵巨大的树,这个解决方案可能会产生性能问题。然后你可以实现一些存储路径的东西或者使用像PostgreSQL ltree这样的解决方案。

答案 1 :(得分:0)

Friendly gem寻求帮助,它大大简化了使用slug的路由。

定义

等路线的替代选项

据我所知,使用动态paramlinks的路由没有好办法,你可以创建一个命名路由来捕获漂亮的嵌套页面路径:

 get '/p/*id', :to => 'pages#show', :as => :nested_pages

另外,请确保更新页面对象的slug以具有嵌套的URL,即:附加父页面' slu to它。例如:

 page1.slug = '/about'
 page2.slug = '/about/team' # team is a child of about
 page3.slug = '/about/team/cameron' # cameron is a child of team

这样你就可以像这样做了

 get '/p/*id', :to => 'pages#show', :via => :get, :as => :nested_pages or pages

因此,为了使这项工作,您可以更改Page模型类中的generate_slug方法:

 def generate_slug
   name_as_slug = name.parameterize
   if parent.present?
     self.slug = [parent.slug, (slug.blank? ? name_as_slug : slug.split('/').last)].join('/')
   else
     self.slug = name_as_slug if slug.blank?
   end
 end