Module: Namespaces::Traversal::Linear
- Extended by:
- ActiveSupport::Concern
- Includes:
- LinearScopes
- Defined in:
- app/models/namespaces/traversal/linear.rb
Constant Summary collapse
- UnboundedSearch =
Class.new(StandardError)
Instance Method Summary collapse
- #ancestor_ids(hierarchy_order: nil) ⇒ Object
- #ancestors(hierarchy_order: nil) ⇒ Object
-
#ancestors_upto(top = nil, hierarchy_order: nil) ⇒ Object
Returns all ancestors upto but excluding the top.
- #descendants ⇒ Object
- #parent=(obj) ⇒ Object
- #parent_id=(id) ⇒ Object
- #root_ancestor ⇒ Object
- #self_and_ancestor_ids(hierarchy_order: nil) ⇒ Object
- #self_and_ancestors(hierarchy_order: nil) ⇒ Object
- #self_and_descendant_ids ⇒ Object
- #self_and_descendants ⇒ Object
- #self_and_hierarchy ⇒ Object
- #traversal_ids ⇒ Object
- #traversal_ids=(ids) ⇒ Object
- #use_traversal_ids? ⇒ Boolean
Instance Method Details
#ancestor_ids(hierarchy_order: nil) ⇒ Object
145 146 147 148 149 |
# File 'app/models/namespaces/traversal/linear.rb', line 145 def ancestor_ids(hierarchy_order: nil) return super unless use_traversal_ids? hierarchy_order == :desc ? traversal_ids[0..-2] : traversal_ids[0..-2].reverse end |
#ancestors(hierarchy_order: nil) ⇒ Object
137 138 139 140 141 142 143 |
# File 'app/models/namespaces/traversal/linear.rb', line 137 def ancestors(hierarchy_order: nil) return super unless use_traversal_ids? return self.class.none if parent_id.blank? lineage(bottom: parent, hierarchy_order: hierarchy_order) end |
#ancestors_upto(top = nil, hierarchy_order: nil) ⇒ Object
Returns all ancestors upto but excluding the top. When no top is given, all ancestors are returned. When top is not found, returns all ancestors.
This copies the behavior of the recursive method. We will deprecate this behavior soon.
157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 |
# File 'app/models/namespaces/traversal/linear.rb', line 157 def ancestors_upto(top = nil, hierarchy_order: nil) return super unless use_traversal_ids? # We can't use a default value in the method definition above because # we need to preserve those specific parameters for super. hierarchy_order ||= :desc top_index = ancestors_upto_top_index(top) ids = traversal_ids[top_index...-1].reverse # WITH ORDINALITY lets us order the result to match traversal_ids order. ids_string = ids.map { |id| Integer(id) }.join(',') from_sql = <<~SQL unnest(ARRAY[#{ids_string}]::bigint[]) WITH ORDINALITY AS ancestors(id, ord) INNER JOIN namespaces ON namespaces.id = ancestors.id SQL self.class .from(Arel.sql(from_sql)) .order('ancestors.ord': hierarchy_order) end |
#descendants ⇒ Object
125 126 127 128 129 |
# File 'app/models/namespaces/traversal/linear.rb', line 125 def descendants return super unless use_traversal_ids? self_and_descendants.where.not(id: id) end |
#parent=(obj) ⇒ Object
193 194 195 196 |
# File 'app/models/namespaces/traversal/linear.rb', line 193 def parent=(obj) super(obj) set_traversal_ids end |
#parent_id=(id) ⇒ Object
198 199 200 201 |
# File 'app/models/namespaces/traversal/linear.rb', line 198 def parent_id=(id) super(id) set_traversal_ids end |
#root_ancestor ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'app/models/namespaces/traversal/linear.rb', line 99 def root_ancestor strong_memoize(:root_ancestor) do if association(:parent).loaded? && parent.present? # This case is possible when parent has not been persisted or we're inside a transaction. parent.root_ancestor elsif parent_id.nil? # There is no parent, so we are the root ancestor. self else Namespace.find_by(id: traversal_ids.first) end end end |
#self_and_ancestor_ids(hierarchy_order: nil) ⇒ Object
187 188 189 190 191 |
# File 'app/models/namespaces/traversal/linear.rb', line 187 def self_and_ancestor_ids(hierarchy_order: nil) return super unless use_traversal_ids? hierarchy_order == :desc ? traversal_ids : traversal_ids.reverse end |
#self_and_ancestors(hierarchy_order: nil) ⇒ Object
179 180 181 182 183 184 185 |
# File 'app/models/namespaces/traversal/linear.rb', line 179 def self_and_ancestors(hierarchy_order: nil) return super unless use_traversal_ids? return self.class.where(id: id) if parent_id.blank? lineage(bottom: self, hierarchy_order: hierarchy_order) end |
#self_and_descendant_ids ⇒ Object
119 120 121 122 123 |
# File 'app/models/namespaces/traversal/linear.rb', line 119 def self_and_descendant_ids return super unless use_traversal_ids? self_and_descendants.as_ids end |
#self_and_descendants ⇒ Object
113 114 115 116 117 |
# File 'app/models/namespaces/traversal/linear.rb', line 113 def self_and_descendants return super unless use_traversal_ids? lineage(top: self) end |
#self_and_hierarchy ⇒ Object
131 132 133 134 135 |
# File 'app/models/namespaces/traversal/linear.rb', line 131 def self_and_hierarchy return super unless use_traversal_ids? self_and_descendants.or(ancestors) end |
#traversal_ids ⇒ Object
89 90 91 |
# File 'app/models/namespaces/traversal/linear.rb', line 89 def traversal_ids read_attribute(:traversal_ids).presence || transient_traversal_ids || [] end |
#traversal_ids=(ids) ⇒ Object
84 85 86 87 |
# File 'app/models/namespaces/traversal/linear.rb', line 84 def traversal_ids=(ids) super(ids) self.transient_traversal_ids = nil end |