Skip to content

Commit

Permalink
WIP: Add virtual depth column support
Browse files Browse the repository at this point in the history
- find way to setup the sql in tests - currently feels so close as this will
  basically match ancestry_depth_sql. But we have a chicken/egg issue with class and table
  may extract to a static method?
- determine if we want to un-deprecate depth_cache_column.
  I wanted to remove because column and option had different spelling, and the extra field didn't buy us too much.
  maybe hardcoding the virtual column name is good enough for now?
  • Loading branch information
kbrock committed Jul 17, 2023
1 parent 5c63748 commit db822ad
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 16 deletions.
35 changes: 20 additions & 15 deletions lib/ancestry/has_ancestry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -70,24 +70,29 @@ def has_ancestry options = {}

# Create ancestry column accessor and set to option or default
if options[:cache_depth]
# Create accessor for column name and set to option or default
self.cattr_accessor :depth_cache_column
self.depth_cache_column =
if options[:cache_depth] == true
options[:depth_cache_column]&.to_s || 'ancestry_depth'
else
options[:cache_depth].to_s
if options[:cache_depth] == :virtual
# local variable
depth_cache_column = 'ancestry_depth'
else
# Create accessor for column name and set to option or default
self.cattr_accessor :depth_cache_column
self.depth_cache_column =
if options[:cache_depth] == true
options[:depth_cache_column]&.to_s || 'ancestry_depth'
else
options[:cache_depth].to_s
end
if options[:depth_cache_column]
ActiveSupport::Deprecation.warn("has_ancestry :depth_cache_column is deprecated. Use :cache_depth instead.")
end
if options[:depth_cache_column]
ActiveSupport::Deprecation.warn("has_ancestry :depth_cache_column is deprecated. Use :cache_depth instead.")
end

# Cache depth in depth cache column before save
before_validation :cache_depth
before_save :cache_depth
# Cache depth in depth cache column before save
before_validation :cache_depth
before_save :cache_depth

# Validate depth column
validates_numericality_of depth_cache_column, :greater_than_or_equal_to => 0, :only_integer => true, :allow_nil => false
# Validate depth column
validates_numericality_of depth_cache_column, :greater_than_or_equal_to => 0, :only_integer => true, :allow_nil => false
end

scope :before_depth, lambda { |depth| where("#{depth_cache_column} < ?", depth) }
scope :to_depth, lambda { |depth| where("#{depth_cache_column} <= ?", depth) }
Expand Down
12 changes: 11 additions & 1 deletion test/environment.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,17 @@ def self.with_model options = {}

ActiveRecord::Base.connection.create_table 'test_nodes', **table_options do |table|
table.send(column_type, options[:ancestry_column], **column_options(force_allow_nil: skip_ancestry))
table.integer options[:cache_depth] == true ? :ancestry_depth : options[:cache_depth] if options[:cache_depth]
case options[:cache_depth]
when true
table.integer :ancestry_depth
when :virtual
# TODO: find a way to use Ancestry::MaterializedPath{,2}#ancestry_depth_sql
t.virtual :ancestry_depth, type: :integer, as: ancestry_depth_sql, stored: true
when nil, false
# no column
else
table.integer options[:cache_depth]
end
if options[:counter_cache]
counter_cache_column = options[:counter_cache] == true ? :children_count : options[:counter_cache]
table.integer counter_cache_column, default: 0, null: false
Expand Down

0 comments on commit db822ad

Please sign in to comment.