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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: abe351194af5c2a75cbaad480fce586064fddad1
4
- data.tar.gz: 283c8fd7fd5b8d27fdbe3b15bc4af195a90b15b5
3
+ metadata.gz: 5ff1f9affc659f62ba4a9b6eb0f25309b980939f
4
+ data.tar.gz: 4de2b383019e35c329b4bb11a3e7c39f1a5b2207
5
5
  SHA512:
6
- metadata.gz: 8b529a4e0c3a0937d215feb5c77647c7ef9e7877ecdca68365bc888789d6abc050675e29ac0526dc27b14f7ece94b610849fdb2a6b982093f6e4ba779a414376
7
- data.tar.gz: 12978bfbbbf31fd2d8ffcaed16c67fe1c029076af8365708ff54cb56de6accfe11879cb80b82fc5fb71880bf20d07ce777fc97550ffcd5cda54a3af3979e8497
6
+ metadata.gz: 8748539cfaf294108ff6d4e3bbf443dd42320171f5e89a0982b00b4aa32f4e6f255b6f3fa0a3726b970b5e7cf6b1b02a48e8bd0e203d892127547afb82c99567
7
+ data.tar.gz: edc08f4f3e803bf13f4d9b8dfd84cd4b690489ddab3daf3f3a39aea833fe44d93a506b50d0319a970f9dacc91b45722b3768b321023ba7ab7dda4246dc169a87
data/CHANGELOG.md CHANGED
@@ -1,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.1
4
+
5
+ - Added path normalization to `.find_by_path`
6
+ - Added `.find_by_path!`
7
+ - Added `#full_path`
8
+ - Fixed boolean options.
9
+ - Added options validation.
10
+
3
11
  ## 0.3.0
4
12
 
5
13
  - Added "path_separator" option.
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
- counter_cache: :children_count,
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.find_by_node_path('bar/qux/quux')
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
- def has_hierarchy(options = {})
9
- cattr_accessor(:has_hierarchy_options) { options }
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
- include Order unless options[:order] == false
15
- include Path unless options[:path_cache] == false
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
@@ -4,12 +4,6 @@ module HasHierarchy
4
4
 
5
5
  included do
6
6
  before_save :cache_depth
7
-
8
- cattr_accessor :depth_column do
9
- column = has_hierarchy_options[:depth_cache]
10
- column = :depth if column == true
11
- column
12
- end
13
7
  end
14
8
 
15
9
  protected
@@ -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
@@ -1,3 +1,3 @@
1
1
  module HasHierarchy
2
- VERSION = '0.3.0'
2
+ VERSION = '0.3.1'
3
3
  end
@@ -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)
@@ -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
- # Ordering scope (parent_id) cannot be combined with lambda.
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.0
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-09-18 00:00:00.000000000 Z
11
+ date: 2014-10-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler