Module: StewEucen::Acts::FertileForest::Table::States
- Defined in:
- lib/fertile_forest/modules/states.rb
Overview
This module is for extending into derived class by ActiveRecord.
The caption contains “Instance Methods”, but it means “Class Methods” of each derived class.
Instance Method Summary collapse
-
#ancestor?(base_obj, researches = []) ⇒ Array
Is reserching node ancestor of base node?.
-
#descendant?(base_obj, researches = []) ⇒ Array
Is reserching node descendant of base node?.
-
#has_descendant?(node_obj) ⇒ Boolean
Has descendant?.
-
#has_sibling?(node_obj) ⇒ Boolean
Has sibling node?.
-
#height(base_obj) ⇒ Integer?
Calculate height of subtree.
-
#internal?(node_obj) ⇒ Boolean
Is internal node? “internal” means non-leaf and non-root.
-
#leaf?(node_obj) ⇒ Boolean
Is leaf node?.
-
#only_child?(node_obj) ⇒ Boolean
Is only child?.
-
#root?(node_obj) ⇒ Boolean
Is root node?.
-
#siblings?(*args) ⇒ Boolean
Are all nodes siblings?.
-
#size(base_obj) ⇒ Integer?
Calculate size of subtree.
Instance Method Details
#ancestor?(base_obj, researches = []) ⇒ Array
Is reserching node ancestor of base node?
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 |
# File 'lib/fertile_forest/modules/states.rb', line 194 def ancestor?(base_obj, researches = []) aim_node = ff_resolve_nodes(base_obj) return nil if aim_node.blank? # nil as dubious is_plural = researches.is_a?(Array) return (is_plural ? [] : nil) if researches.blank? # need to be "id => node" for checking grove research_nodes = ff_resolve_nodes( is_plural ? researches : [researches], true # refresh ) exists_hash = {} Array(ancestors(aim_node)).each { |node| exists_hash[node.id] = true } res = {} research_nodes.each_pair do |the_id, the_node| res[the_id] = exists_hash[the_id] end is_plural ? res : res.values.first end |
#descendant?(base_obj, researches = []) ⇒ Array
Is reserching node descendant of base node?
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 |
# File 'lib/fertile_forest/modules/states.rb', line 152 def descendant?(base_obj, researches = []) aim_node = ff_resolve_nodes(base_obj) return nil if aim_node.blank? # nil as dubious is_plural = researches.is_a?(Array) return (is_plural ? [] : nil) if researches.blank? # need to be "id => node" for checking grove research_nodes = ff_resolve_nodes( is_plural ? researches : [researches], true # refresh ) boundary_queue = ff_get_boundary_queue(aim_node) aim_tail_queue = (boundary_queue.blank? \ ? QUEUE_MAX_VALUE : boundary_queue - 1 ) aim_queue = aim_node.ff_queue aim_grove = aim_node.ff_grove res = {} research_nodes.each_pair do |the_id, the_node| if the_node.present? && the_node.ff_grove == aim_grove the_queue = the_node.ff_queue res[the_id] = aim_queue < the_queue && the_queue <= aim_tail_queue else res[the_id] = nil end end is_plural ? res : res.values.first end |
#has_descendant?(node_obj) ⇒ Boolean
Has descendant?
64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/fertile_forest/modules/states.rb', line 64 def has_descendant?(node_obj) aim_node = ff_resolve_nodes(node_obj) return nil if aim_node.blank? # nil as dubious aim_query = ff_subtree_scope( aim_node, false, # without top true # use COALESCE() ) .select(@_id) # FIXME: When use COALESCE(), can not act query.count # 0 < aim_query.count aim_query.first.present? end |
#has_sibling?(node_obj) ⇒ Boolean
Has sibling node?
110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 |
# File 'lib/fertile_forest/modules/states.rb', line 110 def has_sibling?(node_obj) aim_node = ff_resolve_nodes(node_obj) return nil if aim_node.blank? # nil as dubious aim_depth = aim_node.ff_depth # root node has no sibling return false if aim_depth == ROOT_DEPTH parent_node = genitor(aim_node) # null as dubious, because no parent is irregular return nil if parent_node.blank? ffdd = arel_table[@_ff_depth] aim_query = ff_subtree_scope( parent_node, false, # without top false # use COALESCE() # true # FIXME: COALESCE() true makes error ) .where(ffdd.eq(aim_depth)) 1 < aim_query.count end |
#height(base_obj) ⇒ Integer?
Calculate height of subtree.
When want to get root height as:
(1) get height of any node.
(2) root height = height of the node + depth of the node.
Height of empty tree is “-1”
en.wikipedia.org/wiki/Tree_(data_structure)
229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 |
# File 'lib/fertile_forest/modules/states.rb', line 229 def height(base_obj) aim_node = ff_resolve_nodes(base_obj) return nil if aim_node.blank? # nil as dubious ffdd = arel_table[@_ff_depth] # with top, use COALESCE() height_res = ff_subtree_scope(aim_node, SUBTREE_WITH_TOP_NODE, true) .select(ffdd.maximum.as('ff_height')) .first return nil if height_res.blank? # nil as dubious height_res.ff_height - aim_node.ff_depth end |
#internal?(node_obj) ⇒ Boolean
Is internal node?
"internal" means non-leaf and non-root.
98 99 100 101 102 103 |
# File 'lib/fertile_forest/modules/states.rb', line 98 def internal?(node_obj) aim_node = ff_resolve_nodes(node_obj) return nil if aim_node.blank? # nil as dubious aim_node.ff_depth != ROOT_DEPTH && has_descendant?(node_obj) end |
#leaf?(node_obj) ⇒ Boolean
Is leaf node?
85 86 87 88 89 90 |
# File 'lib/fertile_forest/modules/states.rb', line 85 def leaf?(node_obj) result = has_descendant?(node_obj) # nil as dubious return nil if result.nil? !result end |
#only_child?(node_obj) ⇒ Boolean
Is only child?
139 140 141 142 143 144 |
# File 'lib/fertile_forest/modules/states.rb', line 139 def only_child?(node_obj) has_sibling = has_sibling?(node_obj) return nil if has_sibling.nil? # nil as dubious !has_sibling end |
#root?(node_obj) ⇒ Boolean
Is root node?
52 53 54 55 56 57 |
# File 'lib/fertile_forest/modules/states.rb', line 52 def root?(node_obj) aim_node = ff_resolve_nodes(node_obj) return nil if aim_node.blank? # nil as dubious aim_node.ff_depth == ROOT_DEPTH # never === end |
#siblings?(*args) ⇒ Boolean
is full flag
Are all nodes siblings?
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/fertile_forest/modules/states.rb', line 23 def siblings?(*args) sibling_nodes = ff_resolve_nodes(args.flatten) # get id hash by nested information eldest_node = sibling_nodes.values.first full_sibling_nodes = siblings(eldest_node, [@_id]).all child_hash = {} bingo_count = sibling_nodes.length full_sibling_nodes.each do |the_node| the_id = the_node.id child_hash[the_id] = the_node # ruby has no --xxxx bingo_count -= 1 if sibling_nodes.has_key?(the_id) end # return value if bingo_count == 0 child_hash else false end end |
#size(base_obj) ⇒ Integer?
Calculate size of subtree.
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 |
# File 'lib/fertile_forest/modules/states.rb', line 251 def size(base_obj) aim_node = ff_resolve_nodes(base_obj) return nil if aim_node.blank? # nil as dubious ffdd = arel_table[@_ff_depth] # with top, use COALESCE() size_res = ff_subtree_scope(aim_node, SUBTREE_WITH_TOP_NODE, true) .select(ffdd.count.as('ff_count')) .first return nil if size_res.blank? # nil as dubious size_res.ff_count end |