diff --git a/app/models/category.rb b/app/models/category.rb index b4c5bbf..8180ca8 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -16,21 +16,47 @@ class Category < ActiveRecord::Base acts_as_tree :order => 'name' - - + # calculates the full name of a category by accessing the name of all its + # ancestors. + # + # If you have this category hierarchy: + # Category "A" + # Category "B" + # Category "C" + # + # Then Category "C" will have "A/B/C" as its full name. def full_name(sep = '/') - self.parent ? (self.parent.full_name(sep) + sep + self.name) : (self.name) + my_name = self.name ? self.name : '?' + self.parent ? (self.parent.full_name(sep) + sep + my_name) : (my_name) end + + # calculates the level of the category in the category hierarchy. Top-level + # categories have level 0; the children of the top-level categories have + # level 1; the children of categories with level 1 have level 2, and so on. + # + # A level 0 + # / \ + # B C level 1 + # / \ / \ + # E F G H level 2 + # ... def level self.parent ? (self.parent.level + 1) : 0 end + + # Is this category a top-level category? def top_level? self.parent.nil? end + + # Is this category a leaf in the hierarchy tree of categories? + # + # Being a leaf means that this category has no subcategories. def leaf? self.children.empty? end + # Finds all top level categories for a given environment. def self.top_level_for(environment) self.find(:all, :conditions => ['parent_id is null and environment_id = ?', environment.id ]) end @@ -38,6 +64,7 @@ class Category < ActiveRecord::Base # used to know when to trigger batch renaming attr_accessor :recalculate_path + # sets the name of the category. Also sets #slug accordingly. def name=(value) if self.name != value self.recalculate_path = true @@ -49,6 +76,7 @@ class Category < ActiveRecord::Base end end + # sets the slug of the category. Also sets the path with the new slug value. def slug=(value) self[:slug] = value unless self.slug.blank? diff --git a/test/unit/category_test.rb b/test/unit/category_test.rb index 0be0cbe..1fde71e 100644 --- a/test/unit/category_test.rb +++ b/test/unit/category_test.rb @@ -49,6 +49,13 @@ class CategoryTest < Test::Unit::TestCase assert_equal 'category_name/subcategory_name', sub_cat.full_name end + should 'cope with nil name when calculating full_name' do + cat = Category.new(:name => 'toplevel') + sub = Category.new + sub.parent = cat + assert_equal 'toplevel/?', sub.full_name + end + def test_category_level cat = Category.new(:name => 'category_name') assert_equal 0, cat.level -- libgit2 0.21.2