在我的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
这可以单独使用路由来实现吗?或者我还需要做其他事情吗?
答案 0 :(得分:1)
使用嵌套路由无法实现此目的,但您可以使用route globbing and wildcards。让我概述为您实现它可能需要采取的步骤:
get '*path', to: 'pages#show'
之类的通配符路由添加到路由文件的末尾,否则它将匹配所有其他获取请求。params['path']
操作中获取pages#show
的记录。从最后一段开始,尝试找到它。如果找不到,则该页面不存在。如果你得到最后一个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