Skip to content

Commit

Permalink
Merge branch 'master' of http://github.com/rolftimmermans/ancestry in…
Browse files Browse the repository at this point in the history
…to rolftimmermans-master
  • Loading branch information
Stefan Kroes committed Oct 31, 2010
2 parents e1c95c7 + d8cd386 commit 495cda6
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 77 deletions.
34 changes: 23 additions & 11 deletions lib/ancestry/instance_methods.rb
Expand Up @@ -18,7 +18,7 @@ def update_descendants_with_new_ancestry
descendant.update_attribute(
self.base_class.ancestry_column,
descendant.read_attribute(descendant.class.ancestry_column).gsub(
/^#{self.child_ancestry}/,
/^#{self.child_ancestry}/,
if read_attribute(self.class.ancestry_column).blank? then id.to_s else "#{read_attribute self.class.ancestry_column }/#{id}" end
)
)
Expand Down Expand Up @@ -55,7 +55,7 @@ def apply_orphan_strategy
end
end
end

# The ancestry value for this record's children
def child_ancestry
# New records cannot have children
Expand All @@ -66,7 +66,7 @@ def child_ancestry

# Ancestors
def ancestor_ids
read_attribute(self.base_class.ancestry_column).to_s.split('/').map(&:to_i)
read_attribute(self.base_class.ancestry_column).to_s.split('/').map { |id| cast_primary_key(id) }
end

def ancestor_conditions
Expand All @@ -76,7 +76,7 @@ def ancestor_conditions
def ancestors depth_options = {}
self.base_class.scope_depth(depth_options, depth).ordered_by_ancestry.scoped :conditions => ancestor_conditions
end

def path_ids
ancestor_ids + [id]
end
Expand All @@ -88,11 +88,11 @@ def path_conditions
def path depth_options = {}
self.base_class.scope_depth(depth_options, depth).ordered_by_ancestry.scoped :conditions => path_conditions
end

def depth
ancestor_ids.size
end

def cache_depth
write_attribute self.base_class.depth_cache_column, depth
end
Expand Down Expand Up @@ -181,7 +181,7 @@ def descendants depth_options = {}
def descendant_ids depth_options = {}
descendants(depth_options).all(:select => self.base_class.primary_key).collect(&self.base_class.primary_key.to_sym)
end

# Subtree
def subtree_conditions
["#{self.base_class.primary_key} = ? or #{self.base_class.ancestry_column} like ? or #{self.base_class.ancestry_column} = ?", self.id, "#{child_ancestry}/%", child_ancestry]
Expand All @@ -194,20 +194,20 @@ def subtree depth_options = {}
def subtree_ids depth_options = {}
subtree(depth_options).all(:select => self.base_class.primary_key).collect(&self.base_class.primary_key.to_sym)
end

# Callback disabling
def without_ancestry_callbacks
@disable_ancestry_callbacks = true
yield
@disable_ancestry_callbacks = false
end

def ancestry_callbacks_disabled?
!!@disable_ancestry_callbacks
end

private

# Workaround to support Rails 2
def add_error_to_base error
if rails_3
Expand All @@ -216,5 +216,17 @@ def add_error_to_base error
errors.add_to_base error
end
end

def cast_primary_key(key)
if primary_key_type == :string
key
else
key.to_i
end
end

def primary_key_type
@primary_key_type ||= column_for_attribute(self.class.primary_key).type
end
end
end
13 changes: 9 additions & 4 deletions test/environment.rb
Expand Up @@ -10,13 +10,15 @@ def self.setup
ActiveRecord::Base.logger
ActiveRecord::Base.establish_connection YAML.load(File.open(File.join(File.dirname(__FILE__), 'database.yml')).read)[ENV['db'] || 'sqlite3']
end

def self.with_model options = {}
depth = options.delete(:depth) || 0
width = options.delete(:width) || 0
extra_columns = options.delete(:extra_columns)

ActiveRecord::Base.connection.create_table 'test_nodes' do |table|
primary_key_type = options.delete(:primary_key_type) || :default

ActiveRecord::Base.connection.create_table 'test_nodes', :id => (primary_key_type == :default) do |table|
table.string :id, :null => false if primary_key_type == :string
table.string options[:ancestry_column] || :ancestry
table.integer options[:depth_cache_column] || :ancestry_depth if options[:cache_depth]
extra_columns.each do |name, type|
Expand All @@ -29,6 +31,9 @@ def self.with_model options = {}
(class << model; self; end).send :define_method, :model_name do; Struct.new(:human, :underscore).new 'TestNode', 'test_node'; end
const_set 'TestNode', model

if primary_key_type == :string
model.before_create { self.id = ActiveSupport::SecureRandom.hex(10) }
end
model.send :set_table_name, 'test_nodes'
model.has_ancestry options unless options.delete(:skip_ancestry)

Expand All @@ -42,7 +47,7 @@ def self.with_model options = {}
remove_const "TestNode"
end
end

def self.create_test_nodes model, depth, width, parent = nil
unless depth == 0
Array.new width do
Expand Down

0 comments on commit 495cda6

Please sign in to comment.