Module: MongoNestedSet::ClassMethods
- Defined in:
- lib/mongo_nested_set.rb
Instance Method Summary collapse
-
#all_roots_valid? ⇒ Boolean
Wrapper for each_root_valid? that can deal with scope.
- #base_class ⇒ Object
- #each_root_valid?(roots_to_validate) ⇒ Boolean
-
#each_with_level(objects) ⇒ Object
Iterates over tree elements and determines the current level in the tree.
- #left_and_rights_valid? ⇒ Boolean
- #no_duplicates_for_columns? ⇒ Boolean
-
#rebuild! ⇒ Object
Rebuilds the left & rights if unset or invalid.
-
#root ⇒ Object
Returns the first root.
- #roots ⇒ Object
- #valid? ⇒ Boolean
Instance Method Details
#all_roots_valid? ⇒ Boolean
Wrapper for each_root_valid? that can deal with scope.
110 111 112 113 114 115 116 117 118 |
# File 'lib/mongo_nested_set.rb', line 110 def all_roots_valid? if [:scope] roots.group_by{|record| scope_column_names.collect{|col| record.send(col.to_sym)}}.all? do |scope, grouped_roots| each_root_valid?(grouped_roots) end else each_root_valid?(roots) end end |
#base_class ⇒ Object
68 69 70 71 72 73 74 |
# File 'lib/mongo_nested_set.rb', line 68 def base_class if superclass == Object self else super end end |
#each_root_valid?(roots_to_validate) ⇒ Boolean
120 121 122 123 124 125 126 127 128 |
# File 'lib/mongo_nested_set.rb', line 120 def each_root_valid?(roots_to_validate) left = right = 0 roots_to_validate.all? do |root| returning(root.left > left && root.right > right) do left = root.left right = root.right end end end |
#each_with_level(objects) ⇒ Object
Iterates over tree elements and determines the current level in the tree. Only accepts default ordering, odering by an other column than lft does not work. This method is much more efficent than calling level because it doesn’t require any additional database queries.
Example:
Category.each_with_level(Category.root.self_and_descendants) do |o, level|
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/mongo_nested_set.rb', line 172 def each_with_level(objects) path = [nil] objects.sort_by(&left_column_name.to_sym).each do |o| if o._parent_id != path.last # we are on a new level, did we decent or ascent? if path.include?(o._parent_id) # remove wrong wrong tailing paths elements path.pop while path.last != o._parent_id else path << o._parent_id end end yield(o, path.length - 1) end end |
#left_and_rights_valid? ⇒ Boolean
89 90 91 92 93 94 95 96 97 98 99 |
# File 'lib/mongo_nested_set.rb', line 89 def left_and_rights_valid? find(:all).detect { |node| node.send(left_column_name).nil? || node.send(right_column_name).nil? || node.send(left_column_name) >= node.send(right_column_name) || !node.parent.nil? && ( node.send(left_column_name) <= node.parent.send(left_column_name) || node.send(right_column_name) >= node.parent.send(right_column_name) ) }.nil? end |
#no_duplicates_for_columns? ⇒ Boolean
101 102 103 104 105 106 107 |
# File 'lib/mongo_nested_set.rb', line 101 def no_duplicates_for_columns? find(:all).inject(true) { |memo, node| memo && [left_column_name, right_column_name].inject(true) { |v, column| v && count(node.scoped(column.to_sym => node.send(column))) == 1 } } end |
#rebuild! ⇒ Object
Rebuilds the left & rights if unset or invalid. Also very useful for converting from acts_as_tree.
131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/mongo_nested_set.rb', line 131 def rebuild! # Don't rebuild a valid tree. return true if valid? scope = lambda{ |node| {} } if [:scope] scope = lambda { |node| scope_column_names.inject({}) { |hash, column_name| hash[column_name] = node.send(column_name.to_sym) hash } } end indices = {} set_left_and_rights = lambda do |node| # set left node.send(:"#{left_column_name}=", (indices[scope.call(node)] += 1)) # find find(:all, scope.call(node).merge(parent_column_name => node.id)).each{|n| set_left_and_rights.call(n) } # set right node.send(:"#{right_column_name}=", (indices[scope.call(node)] += 1)) node.save! end # Find root node(s) root_nodes = find(:all, { parent_column_name => nil, :order => "#{left_column_name}, #{right_column_name}, id" }).each do |root_node| # setup index for this scope indices[scope.call(root_node)] ||= 0 set_left_and_rights.call(root_node) end end |
#root ⇒ Object
Returns the first root
77 78 79 |
# File 'lib/mongo_nested_set.rb', line 77 def root find :first, :parent_id => nil end |
#roots ⇒ Object
81 82 83 |
# File 'lib/mongo_nested_set.rb', line 81 def roots find :all, :parent_id => nil, :order => "#{left_column_name} ASC" end |
#valid? ⇒ Boolean
85 86 87 |
# File 'lib/mongo_nested_set.rb', line 85 def valid? left_and_rights_valid? && no_duplicates_for_columns? && all_roots_valid? end |