ancestry 1.2.4 → 1.2.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,6 +1,6 @@
1
1
  = Ancestry
2
2
 
3
- Ancestry is a gem/plugin that allows the records of a Ruby on Rails ActiveRecord model to be organised as a tree structure (or hierarchy). It uses a single, intuitively formatted database column, using a variation on the materialised path pattern. It exposes all the standard tree structure relations (ancestors, parent, root, children, siblings, descendants) and all of them can be fetched in a single sql query. Additional features are STI support, scopes, depth caching, depth constraints, easy migration from older plugins/gems, integrity checking, integrity restoration, arrangement of (sub)tree into hashes and different strategies for dealing with orphaned records.
3
+ Ancestry is a gem/plugin that allows the records of a Ruby on Rails ActiveRecord model to be organised as a tree structure (or hierarchy). It uses a single, intuitively formatted database column, using a variation on the materialised path pattern. It exposes all the standard tree structure relations (ancestors, parent, root, children, siblings, descendants) and all of them can be fetched in a single SQL query. Additional features are STI support, scopes, depth caching, depth constraints, easy migration from older plugins/gems, integrity checking, integrity restoration, arrangement of (sub)tree into hashes and different strategies for dealing with orphaned records.
4
4
 
5
5
  = Installation
6
6
 
@@ -228,7 +228,7 @@ The Ancestry gem comes with a unit test suite consisting of about 1800 assertion
228
228
 
229
229
  = Internals
230
230
 
231
- As can be seen in the previous section, Ancestry stores a path from the root to the parent for every node. This is a variation on the materialised path database pattern. It allows Ancestry to fetch any relation (siblings, descendants, etc.) in a single sql query without the complicated algorithms and incomprehensibility associated with left and right values. Additionally, any inserts, deletes and updates only affect nodes within the affected node's own subtree.
231
+ As can be seen in the previous section, Ancestry stores a path from the root to the parent for every node. This is a variation on the materialised path database pattern. It allows Ancestry to fetch any relation (siblings, descendants, etc.) in a single SQL query without the complicated algorithms and incomprehensibility associated with left and right values. Additionally, any inserts, deletes and updates only affect nodes within the affected node's own subtree.
232
232
 
233
233
  In the example above, the ancestry column is created as a string. This puts a limitation on the depth of the tree of about 40 or 50 levels, which I think may be enough for most users. To increase the maximum depth of the tree, increase the size of the string that is being used or change it to a text to remove the limitation entirely. Changing it to a text will however decrease performance because an index cannot be put on the column in that case.
234
234
 
@@ -238,7 +238,10 @@ The materialised path pattern requires Ancestry to use a 'like' condition in ord
238
238
 
239
239
  The latest version of ancestry is recommended. The three numbers of each version numbers are respectively the major, minor and patch versions. We started with major version 1 because it looks so much better and ancestry was already quite mature and complete when it was published. The major version is only bumped when backwards compatibility is broken. The minor version is bumped when new features are added. The patch version is bumped when bugs are fixed.
240
240
 
241
- - Version 1.2.4 (2011-4-22)
241
+ - Version 1.2.5 (2012-03-15)
242
+ - Fixed warnings: "parenthesize argument(s) for future version"
243
+ - Fixed a bug in the restore_ancestry_integrity! method (thx Arthur Holstvoogd)
244
+ - Version 1.2.4 (2011-04-22)
242
245
  - Prepended table names to column names in queries (thx raelik)
243
246
  - Better check to see if acts_as_tree can be overloaded (thx jims)
244
247
  - Performance inprovements (thx kueda)
@@ -3,7 +3,7 @@ Gem::Specification.new do |s|
3
3
  s.description = 'Organise ActiveRecord model into a tree structure'
4
4
  s.summary = 'Ancestry allows the records of a ActiveRecord model to be organised in a tree structure, using a single, intuitively formatted database column. It exposes all the standard tree structure relations (ancestors, parent, root, children, siblings, descendants) and all of them can be fetched in a single sql query. Additional features are named_scopes, integrity checking, integrity restoration, arrangement of (sub)tree into hashes and different strategies for dealing with orphaned records.'
5
5
 
6
- s.version = '1.2.4'
6
+ s.version = '1.2.5'
7
7
 
8
8
  s.author = 'Stefan Kroes'
9
9
  s.email = 's.a.kroes@gmail.com'
@@ -78,19 +78,19 @@ module Ancestry
78
78
  begin
79
79
  # ... check validity of ancestry column
80
80
  if !node.valid? and !node.errors[node.class.ancestry_column].blank?
81
- raise Ancestry::AncestryIntegrityException.new "Invalid format for ancestry column of node #{node.id}: #{node.read_attribute node.ancestry_column}."
81
+ raise Ancestry::AncestryIntegrityException.new("Invalid format for ancestry column of node #{node.id}: #{node.read_attribute node.ancestry_column}.")
82
82
  end
83
83
  # ... check that all ancestors exist
84
84
  node.ancestor_ids.each do |ancestor_id|
85
85
  unless exists? ancestor_id
86
- raise Ancestry::AncestryIntegrityException.new "Reference to non-existent node in node #{node.id}: #{ancestor_id}."
86
+ raise Ancestry::AncestryIntegrityException.new("Reference to non-existent node in node #{node.id}: #{ancestor_id}.")
87
87
  end
88
88
  end
89
89
  # ... check that all node parents are consistent with values observed earlier
90
90
  node.path_ids.zip([nil] + node.path_ids).each do |node_id, parent_id|
91
91
  parents[node_id] = parent_id unless parents.has_key? node_id
92
92
  unless parents[node_id] == parent_id
93
- raise Ancestry::AncestryIntegrityException.new "Conflicting parent id found in node #{node.id}: #{parent_id || 'nil'} for node #{node_id} while expecting #{parents[node_id] || 'nil'}"
93
+ raise Ancestry::AncestryIntegrityException.new("Conflicting parent id found in node #{node.id}: #{parent_id || 'nil'} for node #{node_id} while expecting #{parents[node_id] || 'nil'}")
94
94
  end
95
95
  end
96
96
  rescue Ancestry::AncestryIntegrityException => integrity_exception
@@ -107,33 +107,36 @@ module Ancestry
107
107
  # Integrity restoration
108
108
  def restore_ancestry_integrity!
109
109
  parents = {}
110
- # For each node ...
111
- self.base_class.find_each do |node|
112
- # ... set its ancestry to nil if invalid
113
- if node.errors[node.class.ancestry_column].blank?
114
- node.without_ancestry_callbacks do
115
- node.update_attribute node.ancestry_column, nil
110
+ # Wrap the whole thing in a transaction ...
111
+ self.base_class.transaction do
112
+ # For each node ...
113
+ self.base_class.find_each do |node|
114
+ # ... set its ancestry to nil if invalid
115
+ if !node.valid? and !node.errors[node.class.ancestry_column].blank?
116
+ node.without_ancestry_callbacks do
117
+ node.update_attribute node.ancestry_column, nil
118
+ end
116
119
  end
117
- end
118
- # ... save parent of this node in parents array if it exists
119
- parents[node.id] = node.parent_id if exists? node.parent_id
120
+ # ... save parent of this node in parents array if it exists
121
+ parents[node.id] = node.parent_id if exists? node.parent_id
120
122
 
121
- # Reset parent id in array to nil if it introduces a cycle
122
- parent = parents[node.id]
123
- until parent.nil? || parent == node.id
124
- parent = parents[parent]
125
- end
126
- parents[node.id] = nil if parent == node.id
127
- end
128
- # For each node ...
129
- self.base_class.find_each do |node|
130
- # ... rebuild ancestry from parents array
131
- ancestry, parent = nil, parents[node.id]
132
- until parent.nil?
133
- ancestry, parent = if ancestry.nil? then parent else "#{parent}/#{ancestry}" end, parents[parent]
123
+ # Reset parent id in array to nil if it introduces a cycle
124
+ parent = parents[node.id]
125
+ until parent.nil? || parent == node.id
126
+ parent = parents[parent]
127
+ end
128
+ parents[node.id] = nil if parent == node.id
134
129
  end
135
- node.without_ancestry_callbacks do
136
- node.update_attribute node.ancestry_column, ancestry
130
+ # For each node ...
131
+ self.base_class.find_each do |node|
132
+ # ... rebuild ancestry from parents array
133
+ ancestry, parent = nil, parents[node.id]
134
+ until parent.nil?
135
+ ancestry, parent = if ancestry.nil? then parent else "#{parent}/#{ancestry}" end, parents[parent]
136
+ end
137
+ node.without_ancestry_callbacks do
138
+ node.update_attribute node.ancestry_column, ancestry
139
+ end
137
140
  end
138
141
  end
139
142
  end
metadata CHANGED
@@ -1,13 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ancestry
3
3
  version: !ruby/object:Gem::Version
4
- hash: 23
5
- prerelease:
4
+ prerelease: false
6
5
  segments:
7
6
  - 1
8
7
  - 2
9
- - 4
10
- version: 1.2.4
8
+ - 5
9
+ version: 1.2.5
11
10
  platform: ruby
12
11
  authors:
13
12
  - Stefan Kroes
@@ -15,18 +14,16 @@ autorequire:
15
14
  bindir: bin
16
15
  cert_chain: []
17
16
 
18
- date: 2011-04-22 00:00:00 +02:00
17
+ date: 2012-03-15 00:00:00 +01:00
19
18
  default_executable:
20
19
  dependencies:
21
20
  - !ruby/object:Gem::Dependency
22
21
  name: activerecord
23
22
  prerelease: false
24
23
  requirement: &id001 !ruby/object:Gem::Requirement
25
- none: false
26
24
  requirements:
27
25
  - - ">="
28
26
  - !ruby/object:Gem::Version
29
- hash: 3
30
27
  segments:
31
28
  - 2
32
29
  - 2
@@ -63,27 +60,23 @@ rdoc_options: []
63
60
  require_paths:
64
61
  - lib
65
62
  required_ruby_version: !ruby/object:Gem::Requirement
66
- none: false
67
63
  requirements:
68
64
  - - ">="
69
65
  - !ruby/object:Gem::Version
70
- hash: 3
71
66
  segments:
72
67
  - 0
73
68
  version: "0"
74
69
  required_rubygems_version: !ruby/object:Gem::Requirement
75
- none: false
76
70
  requirements:
77
71
  - - ">="
78
72
  - !ruby/object:Gem::Version
79
- hash: 3
80
73
  segments:
81
74
  - 0
82
75
  version: "0"
83
76
  requirements: []
84
77
 
85
78
  rubyforge_project:
86
- rubygems_version: 1.4.1
79
+ rubygems_version: 1.3.6
87
80
  signing_key:
88
81
  specification_version: 3
89
82
  summary: Ancestry allows the records of a ActiveRecord model to be organised in a tree structure, using a single, intuitively formatted database column. It exposes all the standard tree structure relations (ancestors, parent, root, children, siblings, descendants) and all of them can be fetched in a single sql query. Additional features are named_scopes, integrity checking, integrity restoration, arrangement of (sub)tree into hashes and different strategies for dealing with orphaned records.