Skip to content

Commit c6f146d

Browse files
committed
Add support for virtual depth column
still need to consider whether to keep depth_cache_column as deprecated
1 parent 3c6fc32 commit c6f146d

File tree

2 files changed

+36
-18
lines changed

2 files changed

+36
-18
lines changed

lib/ancestry/has_ancestry.rb

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -70,26 +70,30 @@ def has_ancestry options = {}
7070

7171
# Create ancestry column accessor and set to option or default
7272
if options[:cache_depth]
73-
# Create accessor for column name and set to option or default
74-
self.cattr_accessor :depth_cache_column
75-
self.depth_cache_column =
76-
if options[:cache_depth] == true
77-
options[:depth_cache_column]&.to_s || 'ancestry_depth'
78-
else
79-
options[:cache_depth].to_s
73+
if options[:cache_depth] == :virtual
74+
# NOTE: not setting self.depth_cache_column so the code does not try to update the column
75+
depth_cache_sql = options[:depth_cache_column]&.to_s || 'ancestry_depth'
76+
else
77+
# Create accessor for column name and set to option or default
78+
self.cattr_accessor :depth_cache_column
79+
self.depth_cache_column =
80+
if options[:cache_depth] == true
81+
options[:depth_cache_column]&.to_s || 'ancestry_depth'
82+
else
83+
options[:cache_depth].to_s
84+
end
85+
if options[:depth_cache_column]
86+
ActiveSupport::Deprecation.warn("has_ancestry :depth_cache_column is deprecated. Use :cache_depth instead.")
8087
end
81-
if options[:depth_cache_column]
82-
ActiveSupport::Deprecation.warn("has_ancestry :depth_cache_column is deprecated. Use :cache_depth instead.")
83-
end
84-
85-
# Cache depth in depth cache column before save
86-
before_validation :cache_depth
87-
before_save :cache_depth
8888

89-
# Validate depth column
90-
validates_numericality_of depth_cache_column, :greater_than_or_equal_to => 0, :only_integer => true, :allow_nil => false
89+
# Cache depth in depth cache column before save
90+
before_validation :cache_depth
91+
before_save :cache_depth
9192

92-
depth_cache_sql = depth_cache_column
93+
# Validate depth column
94+
validates_numericality_of depth_cache_column, :greater_than_or_equal_to => 0, :only_integer => true, :allow_nil => false
95+
depth_cache_sql = depth_cache_column
96+
end
9397
else
9498
# this is not efficient, but it works
9599
depth_cache_sql = ancestry_depth_sql

test/environment.rb

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,21 @@ def self.with_model options = {}
126126

127127
ActiveRecord::Base.connection.create_table 'test_nodes', **table_options do |table|
128128
table.send(column_type, options[:ancestry_column], **column_options(force_allow_nil: skip_ancestry))
129-
table.integer options[:cache_depth] == true ? :ancestry_depth : options[:cache_depth] if options[:cache_depth]
129+
case options[:cache_depth]
130+
when true
131+
table.integer :ancestry_depth
132+
when :virtual
133+
# sorry, this duplicates has_ancestry a little
134+
ancestry_format = options[:ancestry_format] || Ancestry.default_ancestry_format
135+
path_module = ancestry_format == :materialized_path2 ? Ancestry::MaterializedPath2 : Ancestry::MaterializedPath
136+
ancestry_depth_sql = path_module.construct_depth_sql("test_nodes", options[:ancestry_column], '/')
137+
138+
table.virtual :ancestry_depth, type: :integer, as: ancestry_depth_sql, stored: true
139+
when nil, false
140+
# no column
141+
else
142+
table.integer options[:cache_depth]
143+
end
130144
if options[:counter_cache]
131145
counter_cache_column = options[:counter_cache] == true ? :children_count : options[:counter_cache]
132146
table.integer counter_cache_column, default: 0, null: false

0 commit comments

Comments
 (0)