使用嵌套资源的简单Acts_as_tree

时间:2012-04-08 11:20:29

标签: ruby-on-rails nested-routes acts-as-tree

使用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提供了相同的结果,这将导致重复的内容。

4 个答案:

答案 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)

A)

如果您有路由解决方案,并且唯一的问题是您担心重复内容问题,则可以考虑将<link rel="canonical" href="...">添加到从这些请求生成的页面中。但这不是防弹,因为Google认为这是一个建议。

不确定路由globbers解决方案是否会负责生成带有父ID的URL。

B)

您不需要父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一起使用是有意义的。考虑重构您的想法,或者如果时间不晚,请将您的应用程序带到另一个平台。