Module: SimplyCouch::Model::Ancestry::InstanceMethods
- Defined in:
- lib/simply_couch/model/ancestry.rb
Instance Method Summary collapse
- #add_child(child) ⇒ Object
- #ancestors ⇒ Object
- #children ⇒ Object
- #children=(val) ⇒ Object
-
#clear_cached_ancestors ⇒ Object
reset cache attributes for ancestors.
-
#create_tree_path ⇒ Object
Triggered after create, because needs id.
-
#descendants ⇒ Object
Get all descendants.
- #parent ⇒ Object
- #parent=(val) ⇒ Object
- #parent_id ⇒ Object
- #parent_id=(val) ⇒ Object
- #parent_ids ⇒ Object
- #parents ⇒ Object
-
#subtree ⇒ Object
Find subtree of a given page and set children with the result (important to get same children object ids as in descendants).
- #tree_depth ⇒ Object
- #tree_path ⇒ Object
-
#update_tree_path ⇒ Object
Triggered before save.
Instance Method Details
#add_child(child) ⇒ Object
54 55 56 57 58 59 60 61 62 63 64 65 66 67 |
# File 'lib/simply_couch/model/ancestry.rb', line 54 def add_child(child) unless children.include?(child) @children ||= [] @children += [child] child.parent = self # update by_property of child if it differs from parent if root_property = self.class.ancestry_by_property child.send("#{root_property}=", send(root_property)) if send(root_property) != child.send(root_property) end @descendants = nil # reload descendants if requested end child end |
#ancestors ⇒ Object
149 150 151 152 153 |
# File 'lib/simply_couch/model/ancestry.rb', line 149 def ancestors return [] unless parent_ids.any? return [parent] if parent_ids.size == 1 # optimization, parent is pre-loaded many times (self.class.database.couchrest_database.bulk_load(parent_ids)['rows'] || []).map{|h| h['doc']}.compact end |
#children ⇒ Object
5 6 7 8 9 10 11 12 13 |
# File 'lib/simply_couch/model/ancestry.rb', line 5 def children return @children if @children if root_property = self.class.ancestry_by_property @children = self.class.database.view(self.class.children_view(startkey: [send(root_property), id], endkey: [send(root_property), id, {}], reduce: false)) else @children = self.class.database.view(self.class.children_view(startkey: [id], endkey: [id, {}], reduce: false)) end @children end |
#children=(val) ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
# File 'lib/simply_couch/model/ancestry.rb', line 14 def children=(val) @old_descendants = descendants @children = val @children.map(&:subtree) # preload children hierarchy @new_descendants = [] for child in @children for descendant in child.descendants @new_descendants << descendant end end @old_descendants.each{|d| d.instance_variable_set('@parent', nil); d.path_ids = [d.id]} # old descendants become root (@old_descendants - @new_descendants).map(&:save) # Persist old descendants not present in new descendants # update by_property of children if it differs from parent (locale or ... orther field is required to have the same values) if root_property = self.class.ancestry_by_property self_by_property = send(root_property) for child in @children | @new_descendants child.send("#{root_property}=", self_by_property) if self_by_property != child.send(root_property) end end self.class.set_parent(self, @children) # recurring update of parent in subtree of children @descendants = (@children | @new_descendants) clear_cached_ancestors # Return wether all children can be saved :) (@descendants).map(&:save).all? end |
#clear_cached_ancestors ⇒ Object
reset cache attributes for ancestors
44 45 46 47 48 49 50 51 52 |
# File 'lib/simply_couch/model/ancestry.rb', line 44 def clear_cached_ancestors ansi = self while ancestor = ansi.instance_variable_get('@parent').presence ancestor.instance_variable_set('@descendants', nil) ancestor.instance_variable_set('@children', nil) ansi = ancestor end self end |
#create_tree_path ⇒ Object
Triggered after create, because needs id
99 100 101 102 103 104 105 |
# File 'lib/simply_couch/model/ancestry.rb', line 99 def create_tree_path return false unless id newpath = ( (parent && parent.path_ids) || []) + [id] return true if path_ids == newpath self.path_ids = newpath save end |
#descendants ⇒ Object
Get all descendants
70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/simply_couch/model/ancestry.rb', line 70 def descendants return @descendants if @descendants return @descendants = [] if id.blank? if root_property = self.class.ancestry_by_property @descendants = self.class.database.view(self.class.subtree_view(startkey: [send(root_property), id], endkey: [send(root_property), id, {}], reduce: false)).sort_by!{|d| [d.path_ids.size, d.position]} else @descendants = self.class.database.view(self.class.subtree_view(startkey: [id], endkey: [id, {}], reduce: false)).sort_by{|d| [d.path_ids.size, d.position]} end @children = self.class.build_tree(@descendants) @descendants end |
#parent ⇒ Object
107 108 109 110 111 |
# File 'lib/simply_couch/model/ancestry.rb', line 107 def parent return @parent if @parent return @parent = self.class.find(parent_id) if parent_id.present? nil end |
#parent=(val) ⇒ Object
113 114 115 116 117 118 119 120 121 |
# File 'lib/simply_couch/model/ancestry.rb', line 113 def parent=(val) if @parent != val @parent = val update_tree_path @parent.children += [self] unless @parent.children.include?(self) save end val end |
#parent_id ⇒ Object
141 142 143 |
# File 'lib/simply_couch/model/ancestry.rb', line 141 def parent_id @parent_id ||= parent_ids.last end |
#parent_id=(val) ⇒ Object
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/simply_couch/model/ancestry.rb', line 123 def parent_id=(val) if parent_id != val.presence @parent = nil @parent_id = val.presence subtree if persisted? path_ids_will_change! if @parent_id @parent = parent self.path_ids = parent.path_ids + [id] self.class.set_parent(self, @children) if persisted? else self.path_ids = [id] self.class.set_parent(self, @children) if persisted? end @descendants.map(&:save) if persisted? && save end end |
#parent_ids ⇒ Object
145 146 147 |
# File 'lib/simply_couch/model/ancestry.rb', line 145 def parent_ids (path_ids || [])[0..-2] end |
#parents ⇒ Object
154 155 156 |
# File 'lib/simply_couch/model/ancestry.rb', line 154 def parents ancestors end |
#subtree ⇒ Object
Find subtree of a given page and set children with the result (important to get same children object ids as in descendants)
83 84 85 |
# File 'lib/simply_couch/model/ancestry.rb', line 83 def subtree @children = self.class.build_tree(descendants) end |
#tree_depth ⇒ Object
162 163 164 |
# File 'lib/simply_couch/model/ancestry.rb', line 162 def tree_depth (path_ids || [nil]).size - 1 end |
#tree_path ⇒ Object
158 159 160 |
# File 'lib/simply_couch/model/ancestry.rb', line 158 def tree_path ancestors + [self] end |
#update_tree_path ⇒ Object
Triggered before save
88 89 90 91 92 93 94 95 96 |
# File 'lib/simply_couch/model/ancestry.rb', line 88 def update_tree_path return false unless id newpath = ( (parent && parent.path_ids) || []) + [id] if path_ids != newpath path_ids_will_change! self.path_ids = newpath end self end |