7

My model class is:

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

Is it possible to have such recursive route like this: /root_category_slug/child_category_slug/child_of_a_child_category_slug ... and so one

Thank you for any help :)

vooD
  • 2,881
  • 2
  • 25
  • 34

4 Answers4

4

You can do that with regular routes and Route Globbing, so for example,

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

Then in your controller

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

However, note that nested resource routing more than one level deep isn't recommended.

Corey
  • 2,203
  • 17
  • 10
  • I had the same question, and this works perfectly. I would argue Jamis' rule doesn't apply in this case, since the resource itself is represented as a hierarchical structure. (And there's no need to use nested resources/routes in this case anyway). – Kyle Fox May 21 '10 at 19:47
  • I had to use 'match' instead of 'map.connect' and it worked perfectly – Jeremy Lynch Dec 11 '13 at 11:23
  • What should be done as an alternative to nesting more than one deep? The documentation doesn't say. – kingsfoil Aug 12 '14 at 21:29
2

I doubt it, and it's not a good idea. Rails Route mapping code is complex enough without having to dynamically try to encode & decode (possibly) infinite route strings.

simianarmy
  • 1,485
  • 10
  • 13
1

You can use constraints in rails routing. eg:

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 splits your path by "/" , and checks db for last element in db. if not found, skips the route. if any one knows, how to solve it better, would be glad to hear.

SpX
  • 169
  • 2
  • 6
  • heh, i found best solution. then create new category with acts_as_nested_set, you can generate path to root in 1 query. and then just check field "path" => "a/b/c". – SpX Aug 03 '11 at 10:48
0

It's not easy (read: I don't know how to do it) and it's not advised. Imagine if you have 10 categories, you do not want the url to be /categorya/categoryb/categoryc/categoryd/categorye/categoryf/categoryg/categoryh/categoryi/categoryj.

Perhaps a maximum level of 3 would grant you the power you desire, without polluting the URL?

Ryan Bigg
  • 106,965
  • 23
  • 235
  • 261
  • For my opinion level the level should be limited by the model, not by the routing rule. – vooD Apr 03 '10 at 12:44
  • @Ryan Bigg, how would you prefer to write a URL for something like this, assuming you do have n-depth? he's trying to show a category in a certain location in the tree (and it could have others). – Dan Rosenstark Apr 04 '10 at 02:32