# File lib/mongoid-ancestry/instance_methods.rb, line 259 def primary_key_type @primary_key_type ||= self.base_class.fields['_id'].options[:type] end
module Mongoid::Ancestry
Constants
- VERSION
Public Instance Methods
ancestor_conditions()
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 86 def ancestor_conditions { :_id.in => ancestor_ids } end
ancestor_ids()
click to toggle source
Ancestors
# File lib/mongoid-ancestry/instance_methods.rb, line 82 def ancestor_ids read_attribute(self.base_class.ancestry_field).to_s.split('/').map { |id| cast_primary_key(id) } end
ancestors(depth_options = {})
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 90 def ancestors depth_options = {} self.base_class.scope_depth(depth_options, depth).where(ancestor_conditions) end
ancestry_callbacks_disabled?()
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 227 def ancestry_callbacks_disabled? !!@disable_ancestry_callbacks end
ancestry_exclude_self()
click to toggle source
Validate that the ancestors don’t include itself
# File lib/mongoid-ancestry/instance_methods.rb, line 5 def ancestry_exclude_self if ancestor_ids.include? id errors.add(:base, "#{self.class.name.humanize} cannot be a descendant of itself.") end end
apply_orphan_strategy()
click to toggle source
Apply orphan strategy
# File lib/mongoid-ancestry/instance_methods.rb, line 40 def apply_orphan_strategy # Skip this if callbacks are disabled unless ancestry_callbacks_disabled? # If this isn't a new record ... unless new_record? # ... make al children root if orphan strategy is rootify if self.base_class.orphan_strategy == :rootify descendants.each do |descendant| descendant.without_ancestry_callbacks do val = \ unless descendant.ancestry == child_ancestry descendant.read_attribute(descendant.class.ancestry_field).gsub(/^#{child_ancestry}\//, '') end descendant.update_attribute descendant.class.ancestry_field, val end end # ... destroy all descendants if orphan strategy is destroy elsif self.base_class.orphan_strategy == :destroy descendants.all.each do |descendant| descendant.without_ancestry_callbacks { descendant.destroy } end # ... throw an exception if it has children and orphan strategy is restrict elsif self.base_class.orphan_strategy == :restrict raise Error.new('Cannot delete record because it has descendants.') unless is_childless? end end end end
cache_depth()
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 110 def cache_depth write_attribute self.base_class.depth_cache_field, depth end
child_ancestry()
click to toggle source
The ancestry value for this record’s children
# File lib/mongoid-ancestry/instance_methods.rb, line 70 def child_ancestry # New records cannot have children raise Error.new('No child ancestry for new record. Save record before performing tree operations.') if new_record? if self.send("#{self.base_class.ancestry_field}_was").blank? id.to_s else "#{self.send "#{self.base_class.ancestry_field}_was"}/#{id}" end end
child_conditions()
click to toggle source
Children
# File lib/mongoid-ancestry/instance_methods.rb, line 146 def child_conditions {self.base_class.ancestry_field => child_ancestry} end
child_ids()
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 154 def child_ids children.only(:_id).map(&:id) end
children()
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 150 def children self.base_class.where(child_conditions) end
depth()
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 106 def depth ancestor_ids.size end
descendant_conditions()
click to toggle source
Descendants
# File lib/mongoid-ancestry/instance_methods.rb, line 188 def descendant_conditions [ { self.base_class.ancestry_field => /^#{child_ancestry}\// }, { self.base_class.ancestry_field => child_ancestry } ] end
descendant_ids(depth_options = {})
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 199 def descendant_ids depth_options = {} descendants(depth_options).only(:_id).map(&:id) end
descendants(depth_options = {})
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 195 def descendants depth_options = {} self.base_class.scope_depth(depth_options, depth).any_of(descendant_conditions) end
has_children?()
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 158 def has_children? self.children.present? end
has_siblings?()
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 179 def has_siblings? self.siblings.count > 1 end
is_childless?()
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 162 def is_childless? !has_children? end
is_only_child?()
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 183 def is_only_child? !has_siblings? end
is_root?()
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 141 def is_root? read_attribute(self.base_class.ancestry_field).blank? end
parent()
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 128 def parent parent_id.blank? ? nil : self.base_class.find(parent_id) end
parent=(parent)
click to toggle source
Parent
# File lib/mongoid-ancestry/instance_methods.rb, line 115 def parent= parent write_attribute(self.base_class.ancestry_field, parent.blank? ? nil : parent.child_ancestry) end
parent_id()
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 123 def parent_id parent_id = read_attribute(self.base_class.ancestry_field).to_s.split('/').last return cast_primary_key(parent_id) if parent_id end
parent_id=(parent_id)
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 119 def parent_id= parent_id self.parent = parent_id.blank? ? nil : self.base_class.find(parent_id) end
path(depth_options = {})
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 102 def path depth_options = {} self.base_class.scope_depth(depth_options, depth).where(path_conditions) end
path_conditions()
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 98 def path_conditions { :_id.in => path_ids } end
path_ids()
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 94 def path_ids ancestor_ids + [id] end
root()
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 137 def root (root_id == id) ? self : self.base_class.find(root_id) end
root_id()
click to toggle source
Root
# File lib/mongoid-ancestry/instance_methods.rb, line 133 def root_id ancestor_ids.empty? ? id : ancestor_ids.first end
sibling_conditions()
click to toggle source
Siblings
# File lib/mongoid-ancestry/instance_methods.rb, line 167 def sibling_conditions {self.base_class.ancestry_field => read_attribute(self.base_class.ancestry_field)} end
sibling_ids()
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 175 def sibling_ids siblings.only(:_id).map(&:id) end
siblings()
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 171 def siblings self.base_class.where sibling_conditions end
subtree(depth_options = {})
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 212 def subtree depth_options = {} self.base_class.scope_depth(depth_options, depth).any_of(subtree_conditions) end
subtree_conditions()
click to toggle source
Subtree
# File lib/mongoid-ancestry/instance_methods.rb, line 204 def subtree_conditions [ { :_id => id }, { self.base_class.ancestry_field => /^#{child_ancestry}\// }, { self.base_class.ancestry_field => child_ancestry } ] end
subtree_ids(depth_options = {})
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 216 def subtree_ids depth_options = {} subtree(depth_options).only(:_id).map(&:id) end
touch_parent()
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 35 def touch_parent parent.touch end
update_descendants_with_new_ancestry()
click to toggle source
Update descendants with new ancestry
# File lib/mongoid-ancestry/instance_methods.rb, line 12 def update_descendants_with_new_ancestry # Skip this if callbacks are disabled unless ancestry_callbacks_disabled? # If node is valid, not a new record and ancestry was updated ... if changed.include?(self.base_class.ancestry_field.to_s) && !new_record? && valid? # ... for each descendant ... descendants.each do |descendant| # ... replace old ancestry with new ancestry descendant.without_ancestry_callbacks do for_replace = \ if read_attribute(self.class.ancestry_field).blank? id.to_s else "#{read_attribute self.class.ancestry_field}/#{id}" end new_ancestry = descendant.read_attribute(descendant.class.ancestry_field).gsub(/^#{self.child_ancestry}/, for_replace) descendant.update_attribute(self.base_class.ancestry_field, new_ancestry) end end end end end
without_ancestry_callbacks() { || ... }
click to toggle source
Callback disabling
# File lib/mongoid-ancestry/instance_methods.rb, line 221 def without_ancestry_callbacks @disable_ancestry_callbacks = true yield @disable_ancestry_callbacks = false end
Private Instance Methods
bson_objectid_from_string(key)
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 251 def bson_objectid_from_string(key) if Mongoid.mongoid3? Moped::BSON::ObjectId.from_string(key) else BSON::ObjectId.from_string(key) end end
cast_primary_key(key)
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 233 def cast_primary_key(key) if primary_key_type == Integer key.to_i elsif is_primary_key_type_bson_objectid? && key =~ /[a-z0-9]{24}/ bson_objectid_from_string(key) else key end end
is_primary_key_type_bson_objectid?()
click to toggle source
# File lib/mongoid-ancestry/instance_methods.rb, line 243 def is_primary_key_type_bson_objectid? if Mongoid.mongoid3? primary_key_type == Moped::BSON::ObjectId else primary_key_type == BSON::ObjectId end end
primary_key_type()
click to toggle source