has_hierarchy 0.3.0 → 0.3.1
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/CHANGELOG.md +8 -0
- data/README.md +3 -2
- data/lib/has_hierarchy.rb +32 -4
- data/lib/has_hierarchy/depth_cache.rb +0 -6
- data/lib/has_hierarchy/path.rb +9 -15
- data/lib/has_hierarchy/version.rb +1 -1
- data/spec/has_hierarchy_spec.rb +16 -1
- data/spec/support/models.rb +3 -2
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5ff1f9affc659f62ba4a9b6eb0f25309b980939f
|
4
|
+
data.tar.gz: 4de2b383019e35c329b4bb11a3e7c39f1a5b2207
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8748539cfaf294108ff6d4e3bbf443dd42320171f5e89a0982b00b4aa32f4e6f255b6f3fa0a3726b970b5e7cf6b1b02a48e8bd0e203d892127547afb82c99567
|
7
|
+
data.tar.gz: edc08f4f3e803bf13f4d9b8dfd84cd4b690489ddab3daf3f3a39aea833fe44d93a506b50d0319a970f9dacc91b45722b3768b321023ba7ab7dda4246dc169a87
|
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -32,7 +32,8 @@ $ rails g model Item \
|
|
32
32
|
```ruby
|
33
33
|
class Item < ActiveRecord::Base
|
34
34
|
has_hierarchy path_part: :name,
|
35
|
-
|
35
|
+
depth_cache: true,
|
36
|
+
counter_cache: true,
|
36
37
|
dependent: :destroy
|
37
38
|
end
|
38
39
|
|
@@ -71,7 +72,7 @@ Item.ordered.tree
|
|
71
72
|
# }
|
72
73
|
# }
|
73
74
|
|
74
|
-
Item.
|
75
|
+
Item.find_by_path('bar/qux/quux')
|
75
76
|
# => quux
|
76
77
|
```
|
77
78
|
|
data/lib/has_hierarchy.rb
CHANGED
@@ -5,14 +5,25 @@ require 'has_hierarchy/path'
|
|
5
5
|
require 'has_hierarchy/depth_cache'
|
6
6
|
|
7
7
|
module HasHierarchy
|
8
|
-
|
9
|
-
|
8
|
+
DEFAULT_OPTIONS = {
|
9
|
+
scope: nil,
|
10
|
+
order: :position,
|
11
|
+
path_cache: :path,
|
12
|
+
path_part: :id,
|
13
|
+
path_separator: '/',
|
14
|
+
depth_cache: :depth,
|
15
|
+
counter_cache: :children_count,
|
16
|
+
dependent: nil
|
17
|
+
}
|
10
18
|
|
19
|
+
def has_hierarchy(options = {})
|
11
20
|
extend ClassMethods
|
12
21
|
include InstanceMethods
|
13
22
|
|
14
|
-
|
15
|
-
|
23
|
+
setup_has_hierarchy_options(options)
|
24
|
+
|
25
|
+
include Order if options[:order]
|
26
|
+
include Path if options[:path_cache]
|
16
27
|
include DepthCache if options[:depth_cache]
|
17
28
|
|
18
29
|
belongs_to :parent, class_name: self.name,
|
@@ -47,6 +58,23 @@ module HasHierarchy
|
|
47
58
|
|
48
59
|
protected
|
49
60
|
|
61
|
+
def setup_has_hierarchy_options(options)
|
62
|
+
options.assert_valid_keys(DEFAULT_OPTIONS.keys)
|
63
|
+
|
64
|
+
# Set to false if nil.
|
65
|
+
options.reverse_merge!(depth_cache: false, counter_cache: false)
|
66
|
+
|
67
|
+
DEFAULT_OPTIONS.each do |key, value|
|
68
|
+
options[key] = value if options[key].nil? or options[key] == true
|
69
|
+
end
|
70
|
+
|
71
|
+
cattr_accessor(:path_column) { options[:path_cache] }
|
72
|
+
cattr_accessor(:path_part_column) { options[:path_part] }
|
73
|
+
cattr_accessor(:path_separator) { options[:path_separator] }
|
74
|
+
cattr_accessor(:depth_column) { options[:depth_cache] }
|
75
|
+
cattr_accessor(:has_hierarchy_options) { options }
|
76
|
+
end
|
77
|
+
|
50
78
|
def define_tree_scope(tree_scope)
|
51
79
|
scope :tree_scope, case tree_scope
|
52
80
|
when Proc
|
data/lib/has_hierarchy/path.rb
CHANGED
@@ -5,31 +5,21 @@ module HasHierarchy
|
|
5
5
|
included do
|
6
6
|
before_create :populate_path
|
7
7
|
before_update :rebuild_subtree, if: :need_to_rebuild_subtree?
|
8
|
-
|
9
|
-
cattr_accessor :path_column do
|
10
|
-
column = has_hierarchy_options[:path_cache]
|
11
|
-
column = :path if column.nil? or column == true
|
12
|
-
column
|
13
|
-
end
|
14
|
-
|
15
|
-
cattr_accessor :path_separator do
|
16
|
-
has_hierarchy_options[:path_separator] || '/'
|
17
|
-
end
|
18
|
-
|
19
|
-
cattr_accessor :path_part_column do
|
20
|
-
has_hierarchy_options[:path_part] || :id
|
21
|
-
end
|
22
8
|
end
|
23
9
|
|
24
10
|
module ClassMethods
|
25
11
|
def find_by_path(path)
|
26
12
|
sep = path_separator
|
27
|
-
parts = path.split(sep)
|
13
|
+
parts = path.gsub(/\#{sep}*$/, '').split(sep)
|
28
14
|
part = parts.pop
|
29
15
|
path = parts.length > 0 ? parts.join(sep) + sep : ''
|
30
16
|
|
31
17
|
where(path_part_column => part, path_column => path).first
|
32
18
|
end
|
19
|
+
|
20
|
+
def find_by_path!(path)
|
21
|
+
find_by_path(path) or raise ActiveRecord::RecordNotFound
|
22
|
+
end
|
33
23
|
end
|
34
24
|
|
35
25
|
def root
|
@@ -72,6 +62,10 @@ module HasHierarchy
|
|
72
62
|
self[path_column] = path
|
73
63
|
end
|
74
64
|
|
65
|
+
def full_path
|
66
|
+
path + path_part
|
67
|
+
end
|
68
|
+
|
75
69
|
protected
|
76
70
|
|
77
71
|
def path_part
|
data/spec/has_hierarchy_spec.rb
CHANGED
@@ -110,11 +110,26 @@ shared_examples 'materialized path' do
|
|
110
110
|
describe '.find_by_path' do
|
111
111
|
it 'returns node' do
|
112
112
|
expect(described_class.find_by_path('bar')).to eq(bar)
|
113
|
-
expect(described_class.find_by_path('bar/qux')).to eq(qux)
|
113
|
+
expect(described_class.find_by_path('bar/qux/')).to eq(qux)
|
114
114
|
expect(described_class.find_by_path('bar/qux/quux')).to eq(quux)
|
115
115
|
end
|
116
116
|
end
|
117
117
|
|
118
|
+
describe '.find_by_path!' do
|
119
|
+
it 'returns node or raises RecordNotFound' do
|
120
|
+
expect(described_class.find_by_path!('bar/qux/')).to eq(qux)
|
121
|
+
expect{ described_class.find_by_path!('wrong') }.to raise_error(ActiveRecord::RecordNotFound)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
describe '#full_path' do
|
126
|
+
it 'returns full node path' do
|
127
|
+
expect(bar.full_path).to eq('bar')
|
128
|
+
expect(qux.full_path).to eq('bar/qux')
|
129
|
+
expect(quux.full_path).to eq('bar/qux/quux')
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
118
133
|
describe '#root' do
|
119
134
|
it 'returns first node ancestor' do
|
120
135
|
expect(baz.root).to eq(bar)
|
data/spec/support/models.rb
CHANGED
@@ -6,7 +6,8 @@ end
|
|
6
6
|
|
7
7
|
class AdjacencyListTreeItem < Item
|
8
8
|
has_hierarchy counter_cache: :children_count,
|
9
|
-
path_cache: false
|
9
|
+
path_cache: false,
|
10
|
+
order: true
|
10
11
|
end
|
11
12
|
|
12
13
|
class MaterializedPathTreeItem < Item
|
@@ -24,6 +25,6 @@ end
|
|
24
25
|
|
25
26
|
class ScopedWithLambdaTreeItem < Item
|
26
27
|
has_hierarchy scope: ->(item){ where(category: item.category) },
|
27
|
-
#
|
28
|
+
# parent_id scope cannot be combined with lambda.
|
28
29
|
order: false
|
29
30
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: has_hierarchy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kolesnikov Danil
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-10-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|