ancestry 2.2.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,7 +2,8 @@ require_relative 'ancestry/class_methods'
2
2
  require_relative 'ancestry/instance_methods'
3
3
  require_relative 'ancestry/exceptions'
4
4
  require_relative 'ancestry/has_ancestry'
5
+ require_relative 'ancestry/materialized_path'
5
6
 
6
7
  module Ancestry
7
8
  ANCESTRY_PATTERN = /\A[0-9]+(\/[0-9]+)*\Z/
8
- end
9
+ end
@@ -29,14 +29,8 @@ module Ancestry
29
29
 
30
30
  # Arrangement
31
31
  def arrange options = {}
32
- scope =
33
- if options[:order].nil?
34
- self.ancestry_base_class.ordered_by_ancestry
35
- else
36
- self.ancestry_base_class.ordered_by_ancestry_and options.delete(:order)
37
- end
38
32
  # Get all nodes ordered by ancestry and start sorting them into an empty hash
39
- arrange_nodes scope.where(options)
33
+ arrange_nodes self.ancestry_base_class.reorder(options.delete(:order)).where(options)
40
34
  end
41
35
 
42
36
  # Arrange array of nodes into a nested hash of the form
@@ -1,104 +1,105 @@
1
- class << ActiveRecord::Base
2
- def has_ancestry options = {}
3
- # Check options
4
- raise Ancestry::AncestryException.new("Options for has_ancestry must be in a hash.") unless options.is_a? Hash
5
- options.each do |key, value|
6
- unless [:ancestry_column, :orphan_strategy, :cache_depth, :depth_cache_column, :touch].include? key
7
- raise Ancestry::AncestryException.new("Unknown option for has_ancestry: #{key.inspect} => #{value.inspect}.")
1
+ module Ancestry
2
+ module HasAncestry
3
+ def has_ancestry options = {}
4
+ # Check options
5
+ raise Ancestry::AncestryException.new("Options for has_ancestry must be in a hash.") unless options.is_a? Hash
6
+ options.each do |key, value|
7
+ unless [:ancestry_column, :orphan_strategy, :cache_depth, :depth_cache_column, :touch].include? key
8
+ raise Ancestry::AncestryException.new("Unknown option for has_ancestry: #{key.inspect} => #{value.inspect}.")
9
+ end
8
10
  end
9
- end
10
11
 
11
- # Include instance methods
12
- include Ancestry::InstanceMethods
13
-
14
- # Include dynamic class methods
15
- extend Ancestry::ClassMethods
16
-
17
- # Create ancestry column accessor and set to option or default
18
- cattr_accessor :ancestry_column
19
- self.ancestry_column = options[:ancestry_column] || :ancestry
20
-
21
- # Create orphan strategy accessor and set to option or default (writer comes from DynamicClassMethods)
22
- cattr_reader :orphan_strategy
23
- self.orphan_strategy = options[:orphan_strategy] || :destroy
24
-
25
- # Save self as base class (for STI)
26
- cattr_accessor :ancestry_base_class
27
- self.ancestry_base_class = self
28
-
29
- # Touch ancestors after updating
30
- cattr_accessor :touch_ancestors
31
- self.touch_ancestors = options[:touch] || false
32
-
33
- # Validate format of ancestry column value
34
- validates_format_of ancestry_column, :with => Ancestry::ANCESTRY_PATTERN, :allow_nil => true
35
-
36
- # Validate that the ancestor ids don't include own id
37
- validate :ancestry_exclude_self
38
-
39
- # Named scopes
40
- scope :roots, lambda { where(ancestry_column => nil) }
41
- scope :ancestors_of, lambda { |object| where(to_node(object).ancestor_conditions) }
42
- scope :children_of, lambda { |object| where(to_node(object).child_conditions) }
43
- scope :descendants_of, lambda { |object| where(to_node(object).descendant_conditions) }
44
- scope :subtree_of, lambda { |object| where(to_node(object).subtree_conditions) }
45
- scope :siblings_of, lambda { |object| where(to_node(object).sibling_conditions) }
46
- scope :ordered_by_ancestry, lambda {
47
- if %w(mysql mysql2 sqlite postgresql).include?(connection.adapter_name.downcase) &&
48
- defined?(ActiveRecord.version) && ActiveRecord.version.to_s >= "5"
49
- reorder("coalesce(#{connection.quote_table_name(table_name)}.#{connection.quote_column_name(ancestry_column)}, '')")
50
- else
51
- reorder("(CASE WHEN #{connection.quote_table_name(table_name)}.#{connection.quote_column_name(ancestry_column)} IS NULL THEN 0 ELSE 1 END), #{connection.quote_table_name(table_name)}.#{connection.quote_column_name(ancestry_column)}")
52
- end
53
- }
54
- scope :ordered_by_ancestry_and, lambda { |order|
55
- if %w(mysql mysql2 sqlite postgresql).include?(connection.adapter_name.downcase) &&
56
- defined?(ActiveRecord.version) && ActiveRecord.version.to_s >= "5"
57
- reorder("coalesce(#{connection.quote_table_name(table_name)}.#{connection.quote_column_name(ancestry_column)}, ''), #{order}")
58
- else
59
- reorder("(CASE WHEN #{connection.quote_table_name(table_name)}.#{connection.quote_column_name(ancestry_column)} IS NULL THEN 0 ELSE 1 END), #{connection.quote_table_name(table_name)}.#{connection.quote_column_name(ancestry_column)}, #{order}")
60
- end
61
- }
62
- scope :path_of, lambda { |object| to_node(object).path }
63
12
 
64
- # Update descendants with new ancestry before save
65
- before_save :update_descendants_with_new_ancestry
13
+ # Create ancestry column accessor and set to option or default
14
+ cattr_accessor :ancestry_column
15
+ self.ancestry_column = options[:ancestry_column] || :ancestry
66
16
 
67
- # Apply orphan strategy before destroy
68
- before_destroy :apply_orphan_strategy
17
+ # Save self as base class (for STI)
18
+ cattr_accessor :ancestry_base_class
19
+ self.ancestry_base_class = self
69
20
 
70
- # Create ancestry column accessor and set to option or default
71
- if options[:cache_depth]
72
- # Create accessor for column name and set to option or default
73
- self.cattr_accessor :depth_cache_column
74
- self.depth_cache_column = options[:depth_cache_column] || :ancestry_depth
21
+ # Touch ancestors after updating
22
+ cattr_accessor :touch_ancestors
23
+ self.touch_ancestors = options[:touch] || false
75
24
 
76
- # Cache depth in depth cache column before save
77
- before_validation :cache_depth
78
- before_save :cache_depth
25
+ # Include instance methods
26
+ include Ancestry::InstanceMethods
79
27
 
80
- # Validate depth column
81
- validates_numericality_of depth_cache_column, :greater_than_or_equal_to => 0, :only_integer => true, :allow_nil => false
82
- end
28
+ # Include dynamic class methods
29
+ extend Ancestry::ClassMethods
83
30
 
84
- # Create named scopes for depth
85
- {:before_depth => '<', :to_depth => '<=', :at_depth => '=', :from_depth => '>=', :after_depth => '>'}.each do |scope_name, operator|
86
- scope scope_name, lambda { |depth|
87
- raise Ancestry::AncestryException.new("Named scope '#{scope_name}' is only available when depth caching is enabled.") unless options[:cache_depth]
88
- where("#{depth_cache_column} #{operator} ?", depth)
31
+ extend Ancestry::MaterializedPath
32
+
33
+ # Create orphan strategy accessor and set to option or default (writer comes from DynamicClassMethods)
34
+ cattr_reader :orphan_strategy
35
+ self.orphan_strategy = options[:orphan_strategy] || :destroy
36
+
37
+ # Validate that the ancestor ids don't include own id
38
+ validate :ancestry_exclude_self
39
+
40
+ # Named scopes
41
+ scope :roots, lambda { where(root_conditions) }
42
+ scope :ancestors_of, lambda { |object| where(ancestor_conditions(object)) }
43
+ scope :path_of, lambda { |object| where(path_conditions(object)) }
44
+ scope :children_of, lambda { |object| where(child_conditions(object)) }
45
+ scope :descendants_of, lambda { |object| where(descendant_conditions(object)) }
46
+ scope :subtree_of, lambda { |object| where(subtree_conditions(object)) }
47
+ scope :siblings_of, lambda { |object| where(sibling_conditions(object)) }
48
+ scope :ordered_by_ancestry, Proc.new { |order|
49
+ if %w(mysql mysql2 sqlite sqlite3 postgresql).include?(connection.adapter_name.downcase) && ActiveRecord::VERSION::MAJOR >= 5
50
+ reorder("coalesce(#{connection.quote_table_name(table_name)}.#{connection.quote_column_name(ancestry_column)}, '')", order)
51
+ else
52
+ reorder("(CASE WHEN #{connection.quote_table_name(table_name)}.#{connection.quote_column_name(ancestry_column)} IS NULL THEN 0 ELSE 1 END), #{connection.quote_table_name(table_name)}.#{connection.quote_column_name(ancestry_column)}", order)
53
+ end
89
54
  }
55
+ scope :ordered_by_ancestry_and, Proc.new { |order| ordered_by_ancestry_and(order) }
56
+ scope :path_of, lambda { |object| to_node(object).path }
57
+
58
+ # Update descendants with new ancestry before save
59
+ before_save :update_descendants_with_new_ancestry
60
+
61
+ # Apply orphan strategy before destroy
62
+ before_destroy :apply_orphan_strategy
63
+
64
+ # Create ancestry column accessor and set to option or default
65
+ if options[:cache_depth]
66
+ # Create accessor for column name and set to option or default
67
+ self.cattr_accessor :depth_cache_column
68
+ self.depth_cache_column = options[:depth_cache_column] || :ancestry_depth
69
+
70
+ # Cache depth in depth cache column before save
71
+ before_validation :cache_depth
72
+ before_save :cache_depth
73
+
74
+ # Validate depth column
75
+ validates_numericality_of depth_cache_column, :greater_than_or_equal_to => 0, :only_integer => true, :allow_nil => false
76
+ end
77
+
78
+ # Create named scopes for depth
79
+ {:before_depth => '<', :to_depth => '<=', :at_depth => '=', :from_depth => '>=', :after_depth => '>'}.each do |scope_name, operator|
80
+ scope scope_name, lambda { |depth|
81
+ raise Ancestry::AncestryException.new("Named scope '#{scope_name}' is only available when depth caching is enabled.") unless options[:cache_depth]
82
+ where("#{depth_cache_column} #{operator} ?", depth)
83
+ }
84
+ end
85
+
86
+ after_touch :touch_ancestors_callback
87
+ after_destroy :touch_ancestors_callback
88
+
89
+ if ActiveRecord::VERSION::STRING >= '5.1.0'
90
+ after_save :touch_ancestors_callback, if: :saved_changes?
91
+ else
92
+ after_save :touch_ancestors_callback, if: :changed?
93
+ end
90
94
  end
91
95
 
92
- after_touch :touch_ancestors_callback
93
- after_destroy :touch_ancestors_callback
94
- after_save :touch_ancestors_callback, if: :changed?
96
+ def acts_as_tree(*args)
97
+ return super if defined?(super)
98
+ has_ancestry(*args)
99
+ end
95
100
  end
96
101
  end
97
102
 
98
103
  ActiveSupport.on_load :active_record do
99
- if not(ActiveRecord::Base.respond_to?(:acts_as_tree))
100
- class << ActiveRecord::Base
101
- alias_method :acts_as_tree, :has_ancestry
102
- end
103
- end
104
+ send :extend, Ancestry::HasAncestry
104
105
  end
@@ -7,22 +7,19 @@ module Ancestry
7
7
 
8
8
  # Update descendants with new ancestry
9
9
  def update_descendants_with_new_ancestry
10
- # Skip this if callbacks are disabled
11
- unless ancestry_callbacks_disabled?
12
- # If node is not a new record and ancestry was updated and the new ancestry is sane ...
13
- if ancestry_changed? && !new_record? && sane_ancestry?
14
- # ... for each descendant ...
15
- unscoped_descendants.each do |descendant|
16
- # ... replace old ancestry with new ancestry
17
- descendant.without_ancestry_callbacks do
18
- descendant.update_attribute(
19
- self.ancestry_base_class.ancestry_column,
20
- descendant.read_attribute(descendant.class.ancestry_column).gsub(
21
- /^#{self.child_ancestry}/,
22
- if read_attribute(self.class.ancestry_column).blank? then id.to_s else "#{read_attribute self.class.ancestry_column }/#{id}" end
23
- )
10
+ # If enabled and node is existing and ancestry was updated and the new ancestry is sane ...
11
+ if !ancestry_callbacks_disabled? && !new_record? && ancestry_changed? && sane_ancestry?
12
+ # ... for each descendant ...
13
+ unscoped_descendants.each do |descendant|
14
+ # ... replace old ancestry with new ancestry
15
+ descendant.without_ancestry_callbacks do
16
+ descendant.update_attribute(
17
+ self.ancestry_base_class.ancestry_column,
18
+ descendant.read_attribute(descendant.class.ancestry_column).gsub(
19
+ /^#{self.child_ancestry}/,
20
+ if ancestors? then "#{read_attribute self.class.ancestry_column }/#{id}" else id.to_s end
24
21
  )
25
- end
22
+ )
26
23
  end
27
24
  end
28
25
  end
@@ -30,56 +27,47 @@ module Ancestry
30
27
 
31
28
  # Apply orphan strategy
32
29
  def apply_orphan_strategy
33
- # Skip this if callbacks are disabled
34
- unless ancestry_callbacks_disabled?
35
- # If this isn't a new record ...
36
- unless new_record?
37
- # ... make all children root if orphan strategy is rootify
38
- if self.ancestry_base_class.orphan_strategy == :rootify
39
- unscoped_descendants.each do |descendant|
40
- descendant.without_ancestry_callbacks do
41
- descendant.update_attribute descendant.class.ancestry_column, (if descendant.ancestry == child_ancestry then nil else descendant.ancestry.gsub(/^#{child_ancestry}\//, '') end)
30
+ if !ancestry_callbacks_disabled? && !new_record?
31
+ case self.ancestry_base_class.orphan_strategy
32
+ when :rootify # make all children root if orphan strategy is rootify
33
+ unscoped_descendants.each do |descendant|
34
+ descendant.without_ancestry_callbacks do
35
+ new_ancestry = if descendant.ancestry == child_ancestry
36
+ nil
37
+ else
38
+ descendant.ancestry.gsub(/^#{child_ancestry}\//, '')
42
39
  end
40
+ descendant.update_attribute descendant.class.ancestry_column, new_ancestry
43
41
  end
44
- # ... destroy all descendants if orphan strategy is destroy
45
- elsif self.ancestry_base_class.orphan_strategy == :destroy
46
- unscoped_descendants.each do |descendant|
47
- descendant.without_ancestry_callbacks do
48
- descendant.destroy
49
- end
42
+ end
43
+ when :destroy # destroy all descendants if orphan strategy is destroy
44
+ unscoped_descendants.each do |descendant|
45
+ descendant.without_ancestry_callbacks do
46
+ descendant.destroy
50
47
  end
51
- # ... make child elements of this node, child of its parent if orphan strategy is adopt
52
- elsif self.ancestry_base_class.orphan_strategy == :adopt
53
- descendants.each do |descendant|
54
- descendant.without_ancestry_callbacks do
55
- new_ancestry = descendant.ancestor_ids.delete_if { |x| x == self.id }.join("/")
56
- # check for empty string if it's then set to nil
57
- new_ancestry = nil if new_ancestry.empty?
58
- descendant.update_attribute descendant.class.ancestry_column, new_ancestry || nil
59
- end
48
+ end
49
+ when :adopt # make child elements of this node, child of its parent
50
+ descendants.each do |descendant|
51
+ descendant.without_ancestry_callbacks do
52
+ new_ancestry = descendant.ancestor_ids.delete_if { |x| x == self.id }.join("/")
53
+ # check for empty string if it's then set to nil
54
+ new_ancestry = nil if new_ancestry.empty?
55
+ descendant.update_attribute descendant.class.ancestry_column, new_ancestry || nil
60
56
  end
61
- # ... throw an exception if it has children and orphan strategy is restrict
62
- elsif self.ancestry_base_class.orphan_strategy == :restrict
63
- raise Ancestry::AncestryException.new('Cannot delete record because it has descendants.') unless is_childless?
64
57
  end
58
+ when :restrict # throw an exception if it has children
59
+ raise Ancestry::AncestryException.new('Cannot delete record because it has descendants.') unless is_childless?
65
60
  end
66
61
  end
67
62
  end
68
63
 
69
64
  # Touch each of this record's ancestors
70
65
  def touch_ancestors_callback
71
-
72
- # Skip this if callbacks are disabled
73
- unless ancestry_callbacks_disabled?
74
-
75
- # Only touch if the option is enabled
76
- if self.ancestry_base_class.touch_ancestors
77
-
78
- # Touch each of the old *and* new ancestors
79
- self.class.where(id: (ancestor_ids + ancestor_ids_was).uniq).each do |ancestor|
80
- ancestor.without_ancestry_callbacks do
81
- ancestor.touch
82
- end
66
+ if !ancestry_callbacks_disabled? && self.ancestry_base_class.touch_ancestors
67
+ # Touch each of the old *and* new ancestors
68
+ unscoped_current_and_previous_ancestors.each do |ancestor|
69
+ ancestor.without_ancestry_callbacks do
70
+ ancestor.touch
83
71
  end
84
72
  end
85
73
  end
@@ -95,6 +83,11 @@ module Ancestry
95
83
 
96
84
  # Ancestors
97
85
 
86
+ def ancestors?
87
+ # ancestor_ids.present?
88
+ read_attribute(self.ancestry_base_class.ancestry_column).present?
89
+ end
90
+
98
91
  def ancestry_changed?
99
92
  changed.include?(self.ancestry_base_class.ancestry_column.to_s)
100
93
  end
@@ -108,8 +101,7 @@ module Ancestry
108
101
  end
109
102
 
110
103
  def ancestor_conditions
111
- t = get_arel_table
112
- t[get_primary_key_column].in(ancestor_ids)
104
+ self.ancestry_base_class.ancestor_conditions(self)
113
105
  end
114
106
 
115
107
  def ancestors depth_options = {}
@@ -121,7 +113,13 @@ module Ancestry
121
113
  end
122
114
 
123
115
  def ancestor_ids_was
124
- parse_ancestry_column(changed_attributes[self.ancestry_base_class.ancestry_column.to_s])
116
+ relevant_attributes = if ActiveRecord::VERSION::STRING >= '5.1.0'
117
+ saved_changes.transform_values(&:first)
118
+ else
119
+ changed_attributes
120
+ end
121
+
122
+ parse_ancestry_column(relevant_attributes[self.ancestry_base_class.ancestry_column.to_s])
125
123
  end
126
124
 
127
125
  def path_ids
@@ -129,8 +127,7 @@ module Ancestry
129
127
  end
130
128
 
131
129
  def path_conditions
132
- t = get_arel_table
133
- t[get_primary_key_column].in(path_ids)
130
+ self.ancestry_base_class.path_conditions(self)
134
131
  end
135
132
 
136
133
  def path depth_options = {}
@@ -155,20 +152,20 @@ module Ancestry
155
152
  write_attribute(self.ancestry_base_class.ancestry_column, if parent.nil? then nil else parent.child_ancestry end)
156
153
  end
157
154
 
158
- def parent_id= parent_id
159
- self.parent = if parent_id.blank? then nil else unscoped_find(parent_id) end
155
+ def parent_id= new_parent_id
156
+ self.parent = new_parent_id.present? ? unscoped_find(new_parent_id) : nil
160
157
  end
161
158
 
162
159
  def parent_id
163
- if ancestor_ids.empty? then nil else ancestor_ids.last end
160
+ ancestor_ids.last if ancestors?
164
161
  end
165
162
 
166
163
  def parent
167
- if parent_id.blank? then nil else unscoped_find(parent_id) end
164
+ unscoped_find(parent_id) if ancestors?
168
165
  end
169
166
 
170
167
  def parent_id?
171
- parent_id.present?
168
+ ancestors?
172
169
  end
173
170
 
174
171
  def parent_of?(node)
@@ -178,11 +175,11 @@ module Ancestry
178
175
  # Root
179
176
 
180
177
  def root_id
181
- if ancestor_ids.empty? then id else ancestor_ids.first end
178
+ ancestors? ? ancestor_ids.first : id
182
179
  end
183
180
 
184
181
  def root
185
- if root_id == id then self else unscoped_find(root_id) end
182
+ ancestors? ? unscoped_find(root_id) : self
186
183
  end
187
184
 
188
185
  def is_root?
@@ -197,8 +194,7 @@ module Ancestry
197
194
  # Children
198
195
 
199
196
  def child_conditions
200
- t = get_arel_table
201
- t[get_ancestry_column].eq(child_ancestry)
197
+ self.ancestry_base_class.child_conditions(self)
202
198
  end
203
199
 
204
200
  def children
@@ -206,11 +202,11 @@ module Ancestry
206
202
  end
207
203
 
208
204
  def child_ids
209
- children.select(self.ancestry_base_class.primary_key).map(&self.ancestry_base_class.primary_key.to_sym)
205
+ children.pluck(self.ancestry_base_class.primary_key)
210
206
  end
211
207
 
212
208
  def has_children?
213
- self.children.exists?({})
209
+ self.children.exists?
214
210
  end
215
211
  alias_method :children?, :has_children?
216
212
 
@@ -226,8 +222,7 @@ module Ancestry
226
222
  # Siblings
227
223
 
228
224
  def sibling_conditions
229
- t = get_arel_table
230
- t[get_ancestry_column].eq(read_attribute(self.ancestry_base_class.ancestry_column))
225
+ self.ancestry_base_class.sibling_conditions(self)
231
226
  end
232
227
 
233
228
  def siblings
@@ -235,7 +230,7 @@ module Ancestry
235
230
  end
236
231
 
237
232
  def sibling_ids
238
- siblings.select(self.ancestry_base_class.primary_key).collect(&self.ancestry_base_class.primary_key.to_sym)
233
+ siblings.pluck(self.ancestry_base_class.primary_key)
239
234
  end
240
235
 
241
236
  def has_siblings?
@@ -255,13 +250,7 @@ module Ancestry
255
250
  # Descendants
256
251
 
257
252
  def descendant_conditions
258
- t = get_arel_table
259
- # rails has case sensitive matching.
260
- if defined?(ActiveRecord.version) && ActiveRecord.version.to_s >= "5"
261
- t[get_ancestry_column].matches("#{child_ancestry}/%", nil, true).or(t[get_ancestry_column].eq(child_ancestry))
262
- else
263
- t[get_ancestry_column].matches("#{child_ancestry}/%").or(t[get_ancestry_column].eq(child_ancestry))
264
- end
253
+ self.ancestry_base_class.descendant_conditions(self)
265
254
  end
266
255
 
267
256
  def descendants depth_options = {}
@@ -269,7 +258,7 @@ module Ancestry
269
258
  end
270
259
 
271
260
  def descendant_ids depth_options = {}
272
- descendants(depth_options).select(self.ancestry_base_class.primary_key).collect(&self.ancestry_base_class.primary_key.to_sym)
261
+ descendants(depth_options).pluck(self.ancestry_base_class.primary_key)
273
262
  end
274
263
 
275
264
  def descendant_of?(node)
@@ -279,8 +268,7 @@ module Ancestry
279
268
  # Subtree
280
269
 
281
270
  def subtree_conditions
282
- t = get_arel_table
283
- descendant_conditions.or(t[get_primary_key_column].eq(self.id))
271
+ self.ancestry_base_class.subtree_conditions(self)
284
272
  end
285
273
 
286
274
  def subtree depth_options = {}
@@ -288,7 +276,7 @@ module Ancestry
288
276
  end
289
277
 
290
278
  def subtree_ids depth_options = {}
291
- subtree(depth_options).select(self.ancestry_base_class.primary_key).collect(&self.ancestry_base_class.primary_key.to_sym)
279
+ subtree(depth_options).pluck(self.ancestry_base_class.primary_key)
292
280
  end
293
281
 
294
282
  # Callback disabling
@@ -323,26 +311,14 @@ module Ancestry
323
311
  end
324
312
  end
325
313
 
326
- # Validates the ancestry, but can also be applied if validation is bypassed to determine if children should be affected
327
- def sane_ancestry?
328
- ancestry_value = read_attribute(self.ancestry_base_class.ancestry_column)
329
- ancestry_value.nil? || (ancestry_value.to_s =~ Ancestry::ANCESTRY_PATTERN && !ancestor_ids.include?(self.id))
314
+ def unscoped_current_and_previous_ancestors
315
+ self.ancestry_base_class.unscoped do
316
+ self.ancestry_base_class.where id: (ancestor_ids + ancestor_ids_was).uniq
317
+ end
330
318
  end
331
319
 
332
320
  def unscoped_find id
333
321
  self.ancestry_base_class.unscoped { self.ancestry_base_class.find(id) }
334
322
  end
335
-
336
- def get_arel_table
337
- self.ancestry_base_class.arel_table
338
- end
339
-
340
- def get_primary_key_column
341
- self.ancestry_base_class.primary_key.to_sym
342
- end
343
-
344
- def get_ancestry_column
345
- self.ancestry_base_class.ancestry_column.to_sym
346
- end
347
323
  end
348
324
  end