acts_as_recursive_tree 2.0.2 → 2.1.0
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 +5 -5
- data/CHANGELOG.md +5 -0
- data/lib/acts_as_recursive_tree.rb +1 -0
- data/lib/acts_as_recursive_tree/acts_macro.rb +3 -6
- data/lib/acts_as_recursive_tree/associations.rb +3 -3
- data/lib/acts_as_recursive_tree/builders.rb +1 -0
- data/lib/acts_as_recursive_tree/builders/leaves.rb +1 -1
- data/lib/acts_as_recursive_tree/builders/relation_builder.rb +23 -12
- data/lib/acts_as_recursive_tree/builders/strategy.rb +27 -0
- data/lib/acts_as_recursive_tree/builders/strategy/join.rb +29 -0
- data/lib/acts_as_recursive_tree/builders/strategy/subselect.rb +23 -0
- data/lib/acts_as_recursive_tree/config.rb +22 -0
- data/lib/acts_as_recursive_tree/version.rb +1 -1
- metadata +7 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: a28e3f6eadbc8b37622ef525b25e654b13c0903f4053adb096f4f853f36ccc06
|
4
|
+
data.tar.gz: f2614872c77bf263526ac596bbb82438b75af1e49e393c6464e07515c5605288
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9a4ccf41395828283e882f8e88b6e9c8a7edea75995219840d2c6d07da69bbb8bb6f15aeec6cddf8a105f4f8ad15d3dfddad2bf7aaeead54074fffa28030bd68
|
7
|
+
data.tar.gz: c48904528902e0554d1a46dea5883afcc28473597f4df2493ccf1015e80967b2490cae5f41fb5dac9eb7925a2c9d00feeb9637b902366e3dc1be0d6dddc3c7ab
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
### Version 2.1.0
|
2
|
+
- BUGFIX association self_and_siblings not working
|
3
|
+
- BUGFIX primary_key of model is retrieved on first usage and not on setup
|
4
|
+
- NEW when no ordering/depth is required, then use subselect instead of joining the temp table
|
5
|
+
|
1
6
|
### Version 2.0.2
|
2
7
|
- fix for condition relation was executed before merging
|
3
8
|
|
@@ -1,5 +1,3 @@
|
|
1
|
-
require 'ostruct'
|
2
|
-
|
3
1
|
module ActsAsRecursiveTree
|
4
2
|
module ActsMacro
|
5
3
|
|
@@ -11,11 +9,10 @@ module ActsAsRecursiveTree
|
|
11
9
|
def recursive_tree(parent_key: :parent_id, parent_type_column: nil)
|
12
10
|
|
13
11
|
class_attribute :_recursive_tree_config
|
14
|
-
self._recursive_tree_config =
|
15
|
-
|
12
|
+
self._recursive_tree_config = Config.new(
|
13
|
+
model_class: self,
|
16
14
|
parent_key: parent_key.to_sym,
|
17
|
-
parent_type_column: parent_type_column.try(:to_sym)
|
18
|
-
depth_column: :recursive_depth
|
15
|
+
parent_type_column: parent_type_column.try(:to_sym)
|
19
16
|
)
|
20
17
|
|
21
18
|
include ActsAsRecursiveTree::Model
|
@@ -17,9 +17,9 @@ module ActsAsRecursiveTree
|
|
17
17
|
inverse_of: :parent
|
18
18
|
|
19
19
|
has_many :self_and_siblings,
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
through: :parent,
|
21
|
+
source: :children,
|
22
|
+
class_name: self.base_class.to_s
|
23
23
|
end
|
24
24
|
end
|
25
25
|
end
|
@@ -1,5 +1,8 @@
|
|
1
1
|
module ActsAsRecursiveTree
|
2
2
|
module Builders
|
3
|
+
#
|
4
|
+
# Constructs the Arel necessary for recursion.
|
5
|
+
#
|
3
6
|
class RelationBuilder
|
4
7
|
|
5
8
|
def self.build(klass, ids, exclude_ids: false, &block)
|
@@ -9,6 +12,7 @@ module ActsAsRecursiveTree
|
|
9
12
|
attr_reader :klass, :ids, :recursive_temp_table, :travers_loc_table, :without_ids
|
10
13
|
mattr_reader(:random) { Random.new }
|
11
14
|
|
15
|
+
# Delegators for easier accessing config and query options
|
12
16
|
delegate :primary_key, :depth_column, :parent_key, :parent_type_column, to: :@config
|
13
17
|
delegate :depth_present?, :depth, :condition, :ensure_ordering, to: :@query_opts
|
14
18
|
|
@@ -25,6 +29,13 @@ module ActsAsRecursiveTree
|
|
25
29
|
@travers_loc_table = Arel::Table.new("traverse_#{rand_int}_loc")
|
26
30
|
end
|
27
31
|
|
32
|
+
#
|
33
|
+
# Constructs a new QueryOptions and yield it to the proc if one is present.
|
34
|
+
# Subclasses may override this method to provide sane defaults.
|
35
|
+
#
|
36
|
+
# @param proc [Proc] a proc or nil
|
37
|
+
#
|
38
|
+
# @return [ActsAsRecursiveTree::Options::QueryOptions] the new QueryOptions instance
|
28
39
|
def get_query_options(proc)
|
29
40
|
opts = ActsAsRecursiveTree::Options::QueryOptions.new
|
30
41
|
|
@@ -38,18 +49,9 @@ module ActsAsRecursiveTree
|
|
38
49
|
end
|
39
50
|
|
40
51
|
def build
|
41
|
-
|
42
|
-
create_select_manger.as(recursive_temp_table.name)
|
43
|
-
).on(
|
44
|
-
base_table[primary_key].eq(recursive_temp_table[primary_key])
|
45
|
-
)
|
46
|
-
|
47
|
-
relation = klass.joins(final_select_mgr.join_sources)
|
52
|
+
relation = Strategy.for_query_options(@query_opts).build(self)
|
48
53
|
|
49
54
|
relation = apply_except_id(relation)
|
50
|
-
relation = apply_depth(relation)
|
51
|
-
relation = apply_order(relation)
|
52
|
-
|
53
55
|
relation
|
54
56
|
end
|
55
57
|
|
@@ -69,8 +71,14 @@ module ActsAsRecursiveTree
|
|
69
71
|
relation.order(recursive_temp_table[depth_column].asc)
|
70
72
|
end
|
71
73
|
|
72
|
-
def create_select_manger
|
73
|
-
|
74
|
+
def create_select_manger(column = nil)
|
75
|
+
projections = if column
|
76
|
+
travers_loc_table[column]
|
77
|
+
else
|
78
|
+
Arel.star
|
79
|
+
end
|
80
|
+
|
81
|
+
travers_loc_table.project(projections).with(:recursive, build_cte_table)
|
74
82
|
end
|
75
83
|
|
76
84
|
def build_cte_table
|
@@ -125,6 +133,9 @@ module ActsAsRecursiveTree
|
|
125
133
|
relation.merge(condition)
|
126
134
|
end
|
127
135
|
|
136
|
+
#
|
137
|
+
# U
|
138
|
+
#
|
128
139
|
def build_join_condition
|
129
140
|
raise 'not implemented'
|
130
141
|
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module ActsAsRecursiveTree
|
2
|
+
module Builders
|
3
|
+
#
|
4
|
+
# Strategy module for different strategies of how to build the resulting query.
|
5
|
+
#
|
6
|
+
module Strategy
|
7
|
+
extend ActiveSupport::Autoload
|
8
|
+
|
9
|
+
autoload :Join
|
10
|
+
autoload :Subselect
|
11
|
+
|
12
|
+
#
|
13
|
+
# Returns a Strategy appropriate for query_opts
|
14
|
+
#
|
15
|
+
# @param query_opts [ActsAsRecursiveTree::Options::QueryOptions]
|
16
|
+
#
|
17
|
+
# @return a strategy class best suited for the opts
|
18
|
+
def self.for_query_options(query_opts)
|
19
|
+
if query_opts.depth_present? || query_opts.ensure_ordering
|
20
|
+
Join
|
21
|
+
else
|
22
|
+
Subselect
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module ActsAsRecursiveTree
|
2
|
+
module Builders
|
3
|
+
module Strategy
|
4
|
+
#
|
5
|
+
# Build a relation using an INNER JOIN.
|
6
|
+
#
|
7
|
+
module Join
|
8
|
+
#
|
9
|
+
# Builds the relation.
|
10
|
+
#
|
11
|
+
# @param builder [ActsAsRecursiveTree::Builders::RelationBuilder]
|
12
|
+
# @return [ActiveRecord::Relation]
|
13
|
+
def self.build(builder)
|
14
|
+
final_select_mgr = builder.base_table.join(
|
15
|
+
builder.create_select_manger.as(builder.recursive_temp_table.name)
|
16
|
+
).on(
|
17
|
+
builder.base_table[builder.primary_key].eq(builder.recursive_temp_table[builder.primary_key])
|
18
|
+
)
|
19
|
+
|
20
|
+
relation = builder.klass.joins(final_select_mgr.join_sources)
|
21
|
+
|
22
|
+
relation = builder.apply_depth(relation)
|
23
|
+
relation = builder.apply_order(relation)
|
24
|
+
relation
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module ActsAsRecursiveTree
|
2
|
+
module Builders
|
3
|
+
module Strategy
|
4
|
+
#
|
5
|
+
# Strategy for building a relation using an WHERE ID IN(...).
|
6
|
+
#
|
7
|
+
module Subselect
|
8
|
+
#
|
9
|
+
# Builds the relation.
|
10
|
+
#
|
11
|
+
# @param builder [ActsAsRecursiveTree::Builders::RelationBuilder]
|
12
|
+
# @return [ActiveRecord::Relation]
|
13
|
+
def self.build(builder)
|
14
|
+
builder.klass.where(
|
15
|
+
builder.base_table[builder.primary_key].in(
|
16
|
+
builder.create_select_manger(builder.primary_key)
|
17
|
+
)
|
18
|
+
)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module ActsAsRecursiveTree
|
2
|
+
#
|
3
|
+
# Stores the configuration of one Model class
|
4
|
+
#
|
5
|
+
class Config
|
6
|
+
attr_reader :parent_key, :parent_type_column, :depth_column
|
7
|
+
|
8
|
+
def initialize(model_class:, parent_key:, parent_type_column:, depth_column: :recursive_depth)
|
9
|
+
@model_class = model_class
|
10
|
+
@parent_key = parent_key
|
11
|
+
@parent_type_column = parent_type_column
|
12
|
+
@depth_column = depth_column
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# Returns the primary key for the model class.
|
17
|
+
# @return [Symbol]
|
18
|
+
def primary_key
|
19
|
+
@primary_key ||= @model_class.primary_key.to_sym
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_recursive_tree
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Wolfgang Wedelich-John
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-04-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -127,6 +127,10 @@ files:
|
|
127
127
|
- lib/acts_as_recursive_tree/builders/descendants.rb
|
128
128
|
- lib/acts_as_recursive_tree/builders/leaves.rb
|
129
129
|
- lib/acts_as_recursive_tree/builders/relation_builder.rb
|
130
|
+
- lib/acts_as_recursive_tree/builders/strategy.rb
|
131
|
+
- lib/acts_as_recursive_tree/builders/strategy/join.rb
|
132
|
+
- lib/acts_as_recursive_tree/builders/strategy/subselect.rb
|
133
|
+
- lib/acts_as_recursive_tree/config.rb
|
130
134
|
- lib/acts_as_recursive_tree/model.rb
|
131
135
|
- lib/acts_as_recursive_tree/options.rb
|
132
136
|
- lib/acts_as_recursive_tree/options/depth_condition.rb
|
@@ -165,7 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
165
169
|
version: '0'
|
166
170
|
requirements: []
|
167
171
|
rubyforge_project:
|
168
|
-
rubygems_version: 2.6
|
172
|
+
rubygems_version: 2.7.6
|
169
173
|
signing_key:
|
170
174
|
specification_version: 4
|
171
175
|
summary: Drop in replacement for acts_as_tree but using recursive queries
|
@@ -180,4 +184,3 @@ test_files:
|
|
180
184
|
- spec/model/relation_spec.rb
|
181
185
|
- spec/spec_helper.rb
|
182
186
|
- spec/values_spec.rb
|
183
|
-
has_rdoc:
|