Module: ClosureTree::Model

Extended by:
ActiveSupport::Concern
Defined in:
lib/closure_tree/acts_as_tree.rb

Defined Under Namespace

Modules: ClassMethods

Instance Method Summary collapse

Instance Method Details

#add_child(child_node) ⇒ Object

Alias for appending to the children collection. You can also add directly to the children collection, if you’d prefer.



186
187
188
189
# File 'lib/closure_tree/acts_as_tree.rb', line 186

def add_child(child_node)
  children << child_node
  child_node
end

#ancestor_idsObject



152
153
154
# File 'lib/closure_tree/acts_as_tree.rb', line 152

def ancestor_ids
  ids_from(ancestors)
end

#ancestorsObject



148
149
150
# File 'lib/closure_tree/acts_as_tree.rb', line 148

def ancestors
  without_self(self_and_ancestors)
end

#ancestry_path(to_s_column = name_column) ⇒ Object

Returns an array, root first, of self_and_ancestors’ values of the to_s_column, which defaults to the name_column. (so child.ancestry_path == %w{grandparent parent child}



159
160
161
# File 'lib/closure_tree/acts_as_tree.rb', line 159

def ancestry_path(to_s_column = name_column)
  self_and_ancestors.reverse.collect { |n| n.send to_s_column.to_sym }
end

#child?Boolean

Returns true if this node has a parent, and is not a root.

Returns:

  • (Boolean)


117
118
119
# File 'lib/closure_tree/acts_as_tree.rb', line 117

def child?
  !parent.nil?
end

#depthObject Also known as: level



142
143
144
# File 'lib/closure_tree/acts_as_tree.rb', line 142

def depth
  ancestors.size
end

#descendant_idsObject



167
168
169
# File 'lib/closure_tree/acts_as_tree.rb', line 167

def descendant_ids
  ids_from(descendants)
end

#descendantsObject



163
164
165
# File 'lib/closure_tree/acts_as_tree.rb', line 163

def descendants
  without_self(self_and_descendants)
end

#find_by_path(path) ⇒ Object

Find a child node whose ancestry_path minus self.ancestry_path is path.



192
193
194
195
196
197
198
199
# File 'lib/closure_tree/acts_as_tree.rb', line 192

def find_by_path(path)
  path = path.is_a?(Enumerable) ? path.dup : [path]
  node = self
  while !path.empty? && node
    node = node.children.send("find_by_#{name_column}", path.shift)
  end
  node
end

#find_or_create_by_path(path, attributes = {}) ⇒ Object

Find a child node whose ancestry_path minus self.ancestry_path is path



202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
# File 'lib/closure_tree/acts_as_tree.rb', line 202

def find_or_create_by_path(path, attributes = {})
  path = path.is_a?(Enumerable) ? path.dup : [path]
  node = self
  attrs = {}
  attrs[:type] = self.type if ct_subclass? && ct_has_type?
  path.each do |name|
    attrs[name_sym] = name
    child = node.children.where(attrs).first
    unless child
      child = self.class.new(attributes.merge(attrs))
      node.children << child
    end
    node = child
  end
  node
end

#hash_tree(options = {}) ⇒ Object



219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/closure_tree/acts_as_tree.rb', line 219

def hash_tree(options = {})
  tree = ActiveSupport::OrderedHash.new
  tree[self] = ActiveSupport::OrderedHash.new
  id_to_hash = {self.id => tree[self]}
  scope = descendants
  if options[:limit_depth]
    limit_depth = options[:limit_depth]
    return {} if limit_depth <= 0
    scope = scope.where("generations <= #{limit_depth - 1}")
  end
  scope.each do |ea|
    id_to_hash[ea.ct_parent_id][ea] = (id_to_hash[ea.id] = ActiveSupport::OrderedHash.new)
  end
  tree
end

#leaf?Boolean

Returns true if this node has no children.

Returns:

  • (Boolean)


122
123
124
# File 'lib/closure_tree/acts_as_tree.rb', line 122

def leaf?
  children.empty?
end

#leavesObject



131
132
133
134
135
136
137
138
139
140
# File 'lib/closure_tree/acts_as_tree.rb', line 131

def leaves
  return [self] if leaf?
  self.class.leaves.where(<<-SQL
#{quoted_table_name}.#{self.class.primary_key} IN (
      SELECT descendant_id
      FROM #{quoted_hierarchy_table_name}
      WHERE ancestor_id = #{id})
  SQL
  )
end

#rootObject

Returns the farthest ancestor, or self if root?



127
128
129
# File 'lib/closure_tree/acts_as_tree.rb', line 127

def root
  self_and_ancestors.where(parent_column_name.to_sym => nil).first
end

#root?Boolean

Returns true if this node has no parents.

Returns:

  • (Boolean)


112
113
114
# File 'lib/closure_tree/acts_as_tree.rb', line 112

def root?
  ct_parent_id.nil?
end

#self_and_siblingsObject



171
172
173
174
# File 'lib/closure_tree/acts_as_tree.rb', line 171

def self_and_siblings
  s = self.class.scoped.where(:parent_id => parent)
  quoted_order_column ? s.order(quoted_order_column) : s
end

#sibling_idsObject



180
181
182
# File 'lib/closure_tree/acts_as_tree.rb', line 180

def sibling_ids
  ids_from(siblings)
end

#siblingsObject



176
177
178
# File 'lib/closure_tree/acts_as_tree.rb', line 176

def siblings
  without_self(self_and_siblings)
end