Permalink
Browse files

Merge branch 'master' of http://github.com/rolftimmermans/ancestry in…

…to rolftimmermans-master
  • Loading branch information...
2 parents e1c95c7 + d8cd386 commit 495cda618c1da4d05c39f7cd42a65446c3c21d6b Stefan Kroes committed Oct 31, 2010
Showing with 123 additions and 77 deletions.
  1. +23 −11 lib/ancestry/instance_methods.rb
  2. +9 −4 test/environment.rb
  3. +91 −62 test/has_ancestry_test.rb
@@ -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
)
)
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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]
@@ -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
@@ -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
View
@@ -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|
@@ -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)
@@ -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
Oops, something went wrong.

0 comments on commit 495cda6

Please sign in to comment.