ancestry 3.0.1 → 3.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +53 -53
- data/ancestry.gemspec +2 -0
- data/lib/ancestry.rb +1 -0
- data/lib/ancestry/has_ancestry.rb +3 -3
- data/lib/ancestry/instance_methods.rb +1 -7
- data/lib/ancestry/version.rb +3 -0
- metadata +18 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8088b41fa07084ef6a761d52c2d33b051c24eae3
|
4
|
+
data.tar.gz: ed5f0c0678e1d238adb4b68ed6d6239204c397a1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c97d7541dbba13b6a768edab18a21c2916fbb9ea0f61674f4831a0e56f0eed83bf3b1a18bd743b1f2e0eb26b6b78ca21c69271052e3fb1042d8cf194c74802ca
|
7
|
+
data.tar.gz: 7274762db4aee75b633c14fb158b68da2e4e525c4c5e5557c9c164aa6a2dc8d68c7cdc96f443112a327b0a21b76a3acc57cb09c7653ec5b24a4a839266b7313b
|
data/README.md
CHANGED
@@ -34,19 +34,7 @@ $ bundle install
|
|
34
34
|
## Add ancestry column to your table
|
35
35
|
* Create migration:
|
36
36
|
```bash
|
37
|
-
$ rails g migration add_ancestry_to_[table] ancestry:string
|
38
|
-
```
|
39
|
-
|
40
|
-
* Add index to migration:
|
41
|
-
```ruby
|
42
|
-
# db/migrate/[date]_add_ancestry_to_[table].rb
|
43
|
-
|
44
|
-
class AddAncestryTo[Table] < ActiveRecord::Migration
|
45
|
-
def change
|
46
|
-
add_column [table], :ancestry, :string
|
47
|
-
add_index [table], :ancestry
|
48
|
-
end
|
49
|
-
end
|
37
|
+
$ rails g migration add_ancestry_to_[table] ancestry:string:index
|
50
38
|
```
|
51
39
|
|
52
40
|
* Migrate your database:
|
@@ -95,39 +83,50 @@ node.children.create :name => 'Stinky'
|
|
95
83
|
|
96
84
|
# Navigating your tree
|
97
85
|
|
98
|
-
To navigate an Ancestry model, use the following
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
86
|
+
To navigate an Ancestry model, use the following instance methods:
|
87
|
+
|
88
|
+
| method |return value|
|
89
|
+
|-------------------|------------|
|
90
|
+
|`parent` |parent of the record, nil for a root node|
|
91
|
+
|`parent_id` |parent id of the record, nil for a root node|
|
92
|
+
|`root` |root of the record's tree, self for a root node|
|
93
|
+
|`root_id` |root id of the record's tree, self for a root node|
|
94
|
+
|`root?` <br/> `is_root?` | true if the record is a root node, false otherwise|
|
95
|
+
|`ancestors` |ancestors of the record, starting with the root and ending with the parent|
|
96
|
+
|`ancestors?` |true if the record has ancestors (aka not a root node)|
|
97
|
+
|`ancestor_ids` |ancestor ids of the record|
|
98
|
+
|`path` |path of the record, starting with the root and ending with self|
|
99
|
+
|`path_ids` |a list the path ids, starting with the root id and ending with the node's own id|
|
100
|
+
|`children` |direct children of the record|
|
101
|
+
|`child_ids` |direct children's ids|
|
102
|
+
|`has_parent?` <br/> `ancestors?` |true if the record has a parent, false otherwise|
|
103
|
+
|`has_children?` <br/> `children?` |true if the record has any children, false otherwise|
|
104
|
+
|`is_childless?` <br/> `childless?` |true is the record has no children, false otherwise|
|
105
|
+
|`siblings` |siblings of the record, the record itself is included*|
|
106
|
+
|`sibling_ids` |sibling ids|
|
107
|
+
|`has_siblings?` <br/> `siblings?` |true if the record's parent has more than one child|
|
108
|
+
|`is_only_child?` <br/> `only_child?` |true if the record is the only child of its parent|
|
109
|
+
|`descendants` |direct and indirect children of the record|
|
110
|
+
|`descendant_ids` |direct and indirect children's ids of the record|
|
111
|
+
|`subtree` |the model on descendants and itself|
|
112
|
+
|`subtree_ids` |a list of all ids in the record's subtree|
|
113
|
+
|`depth` |the depth of the node, root nodes are at depth 0|
|
114
|
+
|
115
|
+
\* If the record is a root, other root records are considered siblings
|
116
|
+
\* Siblings returns the record itself
|
117
|
+
|
118
|
+
There are also instance methods to determine the relationship between 2 nodes:
|
119
|
+
|
120
|
+
|method |return value|
|
121
|
+
|-------------------|---------------|
|
122
|
+
|`parent_of?(node)` | node's parent is this record|
|
123
|
+
|`root_of?(node)` | node's root is this record|
|
124
|
+
|`ancestor_of?(node)`| node's ancestors include this record|
|
125
|
+
|`child_of?(node)` | node is record's parent|
|
127
126
|
|
128
127
|
# Options for `has_ancestry`
|
129
128
|
|
130
|
-
The has_ancestry
|
129
|
+
The has_ancestry method supports the following options:
|
131
130
|
|
132
131
|
:ancestry_column Pass in a symbol to store ancestry in a different column
|
133
132
|
:orphan_strategy Instruct Ancestry what to do with children of a node that is destroyed:
|
@@ -155,7 +154,7 @@ example:
|
|
155
154
|
|
156
155
|
```ruby
|
157
156
|
node.children.where(:name => 'Mary').exists?
|
158
|
-
node.subtree.order(:name).limit(10).each
|
157
|
+
node.subtree.order(:name).limit(10).each { ... }
|
159
158
|
node.descendants.count
|
160
159
|
```
|
161
160
|
|
@@ -215,7 +214,7 @@ instead.
|
|
215
214
|
|
216
215
|
Ancestry works fine with STI. Just create a STI inheritance hierarchy and
|
217
216
|
build an Ancestry tree from the different classes/models. All Ancestry
|
218
|
-
relations that
|
217
|
+
relations that were described above will return nodes of any model type. If
|
219
218
|
you do only want nodes of a specific subclass you'll have to add a condition
|
220
219
|
on type for that.
|
221
220
|
|
@@ -225,11 +224,12 @@ Ancestry can arrange an entire subtree into nested hashes for easy navigation
|
|
225
224
|
after retrieval from the database. TreeNode.arrange could for example return:
|
226
225
|
|
227
226
|
```ruby
|
228
|
-
{
|
229
|
-
|
230
|
-
|
231
|
-
=> {}
|
232
|
-
}
|
227
|
+
{
|
228
|
+
#<TreeNode id: 100018, name: "Stinky", ancestry: nil> => {
|
229
|
+
#<TreeNode id: 100019, name: "Crunchy", ancestry: "100018"> => {
|
230
|
+
#<TreeNode id: 100020, name: "Squeeky", ancestry: "100018/100019"> => {}
|
231
|
+
},
|
232
|
+
#<TreeNode id: 100021, name: "Squishy", ancestry: "100018"> => {}
|
233
233
|
}
|
234
234
|
}
|
235
235
|
```
|
@@ -277,7 +277,7 @@ Or plain hashes:
|
|
277
277
|
```ruby
|
278
278
|
TreeNode.arrange_serializable do |parent, children|
|
279
279
|
{
|
280
|
-
my_id: parent.id
|
280
|
+
my_id: parent.id,
|
281
281
|
my_children: children
|
282
282
|
}
|
283
283
|
end
|
@@ -312,7 +312,7 @@ the order of siblings depends on their order in the original array.
|
|
312
312
|
# Migrating from plugin that uses parent_id column
|
313
313
|
|
314
314
|
Most current tree plugins use a parent_id column (has_ancestry,
|
315
|
-
awesome_nested_set, better_nested_set, acts_as_nested_set). With ancestry
|
315
|
+
awesome_nested_set, better_nested_set, acts_as_nested_set). With ancestry it is
|
316
316
|
easy to migrate from any of these plugins, to do so, use the
|
317
317
|
build_ancestry_from_parent_ids! method on your ancestry model. These steps
|
318
318
|
provide a more detailed explanation:
|
@@ -418,7 +418,7 @@ remove the limitation entirely. Changing it to a text will however decrease
|
|
418
418
|
performance because an index cannot be put on the column in that case.
|
419
419
|
|
420
420
|
The materialised path pattern requires Ancestry to use a 'like' condition in
|
421
|
-
order to fetch descendants. The wild character (`%`) is on the
|
421
|
+
order to fetch descendants. The wild character (`%`) is on the right of the
|
422
422
|
query, so indexes should be used.
|
423
423
|
|
424
424
|
# Contributing and license
|
data/ancestry.gemspec
CHANGED
@@ -37,12 +37,14 @@ EOF
|
|
37
37
|
'lib/ancestry/class_methods.rb',
|
38
38
|
'lib/ancestry/instance_methods.rb',
|
39
39
|
'lib/ancestry/materialized_path.rb',
|
40
|
+
'lib/ancestry/version.rb',
|
40
41
|
'MIT-LICENSE',
|
41
42
|
'README.md'
|
42
43
|
]
|
43
44
|
|
44
45
|
s.required_ruby_version = '>= 1.8.7'
|
45
46
|
s.add_runtime_dependency 'activerecord', '>= 3.2.0'
|
47
|
+
s.add_development_dependency 'rdoc'
|
46
48
|
s.add_development_dependency 'yard'
|
47
49
|
s.add_development_dependency 'rake', '~> 10.0'
|
48
50
|
s.add_development_dependency 'test-unit'
|
data/lib/ancestry.rb
CHANGED
@@ -46,12 +46,12 @@ module Ancestry
|
|
46
46
|
scope :siblings_of, lambda { |object| where(sibling_conditions(object)) }
|
47
47
|
scope :ordered_by_ancestry, Proc.new { |order|
|
48
48
|
if %w(mysql mysql2 sqlite sqlite3 postgresql).include?(connection.adapter_name.downcase) && ActiveRecord::VERSION::MAJOR >= 5
|
49
|
-
reorder("coalesce(#{connection.quote_table_name(table_name)}.#{connection.quote_column_name(ancestry_column)}, '')", order)
|
49
|
+
reorder(Arel.sql("coalesce(#{connection.quote_table_name(table_name)}.#{connection.quote_column_name(ancestry_column)}, '')"), order)
|
50
50
|
else
|
51
|
-
reorder("(CASE WHEN #{connection.quote_table_name(table_name)}.#{connection.quote_column_name(ancestry_column)} IS NULL THEN 0 ELSE 1 END), #{connection.quote_table_name(table_name)}.#{connection.quote_column_name(ancestry_column)}", order)
|
51
|
+
reorder(Arel.sql("(CASE WHEN #{connection.quote_table_name(table_name)}.#{connection.quote_column_name(ancestry_column)} IS NULL THEN 0 ELSE 1 END), #{connection.quote_table_name(table_name)}.#{connection.quote_column_name(ancestry_column)}"), order)
|
52
52
|
end
|
53
53
|
}
|
54
|
-
scope :ordered_by_ancestry_and, Proc.new { |order|
|
54
|
+
scope :ordered_by_ancestry_and, Proc.new { |order| ordered_by_ancestry(order) }
|
55
55
|
scope :path_of, lambda { |object| to_node(object).path }
|
56
56
|
|
57
57
|
# Update descendants with new ancestry before save
|
@@ -114,13 +114,7 @@ module Ancestry
|
|
114
114
|
end
|
115
115
|
|
116
116
|
def ancestor_ids_was
|
117
|
-
|
118
|
-
saved_changes.transform_values(&:first)
|
119
|
-
else
|
120
|
-
changed_attributes
|
121
|
-
end
|
122
|
-
|
123
|
-
parse_ancestry_column(relevant_attributes[self.ancestry_base_class.ancestry_column.to_s])
|
117
|
+
parse_ancestry_column(send("#{self.ancestry_base_class.ancestry_column}_was"))
|
124
118
|
end
|
125
119
|
|
126
120
|
def path_ids
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ancestry
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0.
|
4
|
+
version: 3.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Stefan Kroes
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2018-04-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activerecord
|
@@ -25,6 +25,20 @@ dependencies:
|
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: 3.2.0
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rdoc
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ">="
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
28
42
|
- !ruby/object:Gem::Dependency
|
29
43
|
name: yard
|
30
44
|
requirement: !ruby/object:Gem::Requirement
|
@@ -119,6 +133,7 @@ files:
|
|
119
133
|
- lib/ancestry/has_ancestry.rb
|
120
134
|
- lib/ancestry/instance_methods.rb
|
121
135
|
- lib/ancestry/materialized_path.rb
|
136
|
+
- lib/ancestry/version.rb
|
122
137
|
homepage: http://github.com/stefankroes/ancestry
|
123
138
|
licenses:
|
124
139
|
- MIT
|
@@ -143,7 +158,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
143
158
|
version: '0'
|
144
159
|
requirements: []
|
145
160
|
rubyforge_project:
|
146
|
-
rubygems_version: 2.
|
161
|
+
rubygems_version: 2.6.13
|
147
162
|
signing_key:
|
148
163
|
specification_version: 4
|
149
164
|
summary: Organize ActiveRecord model into a tree structure
|