Ruby on Rails中的嵌套路由

7

我的模型类是:

class Category < ActiveRecord::Base
  acts_as_nested_set
  has_many :children, :foreign_key => "parent_id", :class_name => 'Category'
  belongs_to :parent, :foreign_key => "parent_id", :class_name => 'Category' 


  def to_param
    slug
  end
end

是否可能有这样的递归路由,例如: /root_category_slug/child_category_slug/child_of_a_child_category_slug ... 以此类推

感谢任何帮助 :)

4个回答

4

你可以使用常规路由和 路由通配符 来实现此目的,例如:

map.connect 'categories/*slugs', :controller => 'categories', :action => 'show_deeply_nested_category'

然后在你的控制器中

def show_deeply_nested_category
  do_something = params[:slugs]  # contains an array of the path segments
end

但是需要注意的是,不建议使用超过一层嵌套的嵌套资源路由


我曾有同样的问题,这个方案完美解决了。我认为Jamis的规则在这种情况下不适用,因为资源本身就被表示为分层结构。(而且在这种情况下也没有必要使用嵌套资源/路由)。 - Kyle Fox
我不得不使用“match”而不是“map.connect”,它完美地工作了。 - Jeremy Lynch
嵌套超过一层的替代方案是什么?文档中没有提到。 - kingsfoil

2

我觉得这不是个好主意,因为Rails路由映射代码已经足够复杂了,如果动态尝试编码和解码(可能)无限的路由字符串,会让情况更加糟糕。


1

你可以在Rails路由中使用约束。例如:

match '*id', :to => 'categories#show', :constraints => TaxonConstraint.new

class TaxonConstraint
  def matches?(request)
    path = request.path.slice(1..(request.path.length-1)
    path = path.split('/')
    return false if path.length != path.uniq.length
    return true if Category.check(path.last).first
    false
  end
end

class通过“/”将您的路径分割,并在数据库中检查最后一个元素。如果未找到,则跳过该路由。 如果有人知道如何更好地解决这个问题,我很乐意听取建议。


哈哈,我找到了最佳解决方案。然后使用acts_as_nested_set创建新类别,您可以在一个查询中生成到根的路径。然后只需检查字段"path"=>"a/b/c"即可。 - SpX

0

这并不容易(也就是说我不知道怎么做),而且也不建议这样做。想象一下如果你有10个类别,你肯定不希望URL变成/categorya/categoryb/categoryc/categoryd/categorye/categoryf/categoryg/categoryh/categoryi/categoryj

也许只允许3级分类会给你所需的功能,而不会弄脏URL呢?


在我看来,级别应该由模型限制,而不是路由规则限制。 - vooD
@Ryan Bigg,如果您有n-depth,您希望如何编写此类URL?他试图在树的某个位置显示特定类别(可能还有其他类别)。 - Dan Rosenstark

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接