使用Rails 3.1.1和gem acts_as_tree。我在谷歌上搜索了这个问题并检查了类似的问题(答案太旧了,或者说无关紧要)。
我有一个名为文章的模型,其路线今天看起来像:
resources :articles, :path => '', :only => :show
resources :articles, :path => 'articles', :except => :show
我有三篇文章:“book”,“chapter1”和“chapter2”。书籍是第1章和第2章的父母。
今天,我每篇文章的路径是:host.com/book,host.com/chapter1和host.com/chapter2。我希望网址路径为host.com/book/chapter1和host.com/book/chapter2,即嵌套路由。
如何以简洁的方式创建它?
基本上,我想要一个路径为host.com/:parent_id/:parent_id/:id,其中N个为:parent_id。几乎是Wordpress文章的路由。
我不相信路线球形是解决方案,但我可能错了。它似乎给host.com/:id和host.com/foo/bar/:id提供了相同的结果,这将导致重复的内容。
答案 0 :(得分:1)
你有三篇“文章”......“book”,“chapter1”和“chapter2”都代表相同的“资源”,名为“文章”。相同的'资源'不能嵌套。如果需要嵌套路由,则必须单独定义父资源和子资源。以下代码spinet可以帮助您
class Book < ActiveRecord::Base
has_many :chapter
accepts_nested_attributes_for :chapters
end
class Chapter < ActiveRecord::Base
belongs_to :book
acts_as_tree :parent_id
end
答案 1 :(得分:1)
如果您有路由解决方案,并且唯一的问题是您担心重复内容问题,则可以考虑将<link rel="canonical" href="...">
添加到从这些请求生成的页面中。但这不是防弹,因为Google认为这是一个建议。
不确定路由globbers解决方案是否会负责生成带有父ID的URL。
您不需要父ID来执行路由,对吗?您只想将它们包含在网址中并将这些请求与使用example.com/chapter1
这样的网址相同,这是正确的吗?
如果您考虑的解决方案并非纯粹处于Rails级别,那么在Rails处理之前,如何重写这些请求的URL以使/:parent_id/:parent_id/:id
变为/:id
呢?如果存在静态前缀,例如/articles/:parent_id/:parent_id/:id
。
我想你需要编写一些助手来生成带有父ID的URL,以便链接到这些资源。
无论哪种方式,您都需要生成包含父ID的URL,因此如果您只使用这些URL链接到这些资源,则可能不太可能出现重复内容问题。
答案 2 :(得分:0)
match '*p1/*p2/*p3/.../*pn' => 'articles#show'
......不是文字的,只需要根据需要定义尽可能多的参数。
URL:
host.com/book/chapter1
params[:p1] = 'book'
params[:p2] = 'chapter1'
params[:p3] = nil
URL:
host.com/book/chapter1/section2/sentence4
params[:p1] = 'book'
params[:p2] = 'chapter1'
params[:p3] = 'section2'
params[:p4] = 'sentence4'
params[:p5] = nil
那必须是你最后的路线。
我认为它也会使任何catchall路由无法运行,但它们现在已在Rails 3中的默认routes.rb中注释掉,如果使用它们,则必须手动指定通常由旧处理的所有路由风格捕获路线。
而且,如果你有一个名为文章的控制器,你永远不会有一本名为'文章'的书与你的所有控制器相同,为了安全起见,你可能需要重命名你的所有控制器,即文章变成X_articles。你可能永远不会有一本书叫X_articles,等等....
完全未经测试。
答案 3 :(得分:0)
你要做的是使用Rails来制作它不适用的东西。无论你得到什么答案,它都不会是RESTful,DRY,或者与Active Record一起使用是有意义的。考虑重构您的想法,或者如果时间不晚,请将您的应用程序带到另一个平台。