Hierarchical Categories

When we generated scaffold code for categories, we got some basic CRUD screens. But they ignore the fact that our categories are hierarchical. The basic problem is every category item has a parent (except for the root category), and there is no way in the CRUD screens to specify the parent of a category.

For now, we are going to fix this in a very simple way that will get you get up and running quickly. There will be plenty of time later for a fancier user interface.

Every category has a name, but these names are not always individually unique because they are qualified by their parents in the hierarchy. For example, you might have two categories named Car, but one of them might have a parent named Bruce while the other has a parent named Curt. A unique identifier for a category would prefix the category name with all of its parents. So, for these two Car categories, we might have long names like All:Bruce:Car and All:Curt:Car. Let’s implement this attribute as a long_name attribute in our Category model. Edit app/models/category.rb to look like this:

class Category < ActiveRecord::Base
  has_and_belongs_to_many :photos
  acts_as_tree
  def ancestors_name
    if parent
      parent.ancestors_name + parent.name + ':'
    else
      ""
    end
  end

  def long_name
    ancestors_name + name
  end
end

The long_name method returns a string that is the concatenation of the names of all of its parents with its own name. ancestors_name is a recursive method that concatenates all of the parent names with ...

Get Rails: Up and Running, 2nd Edition now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.