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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 064f977e7f4e77083f3a967fce16c6c47fc29ee9
4
- data.tar.gz: 2b8e5949381e248c33034868ee816126367e19bd
2
+ SHA256:
3
+ metadata.gz: a28e3f6eadbc8b37622ef525b25e654b13c0903f4053adb096f4f853f36ccc06
4
+ data.tar.gz: f2614872c77bf263526ac596bbb82438b75af1e49e393c6464e07515c5605288
5
5
  SHA512:
6
- metadata.gz: 91e3f8cdf111f4efed5618391d806ccab6e5bdb2c8e5325862292e23a67d990aaa86de199dfffabade3f0ee6a18ba501d9032e9a700b9dba567eb75e0d6265ec
7
- data.tar.gz: cb6576280d42539dc013e96b07414cae5ad49b416a28518c742731fb43697ec9fc997da237cf8f0cbc5f53c01bf530fd37353bb3108cf9e1e06313c2174aecc9
6
+ metadata.gz: 9a4ccf41395828283e882f8e88b6e9c8a7edea75995219840d2c6d07da69bbb8bb6f15aeec6cddf8a105f4f8ad15d3dfddad2bf7aaeead54074fffa28030bd68
7
+ data.tar.gz: c48904528902e0554d1a46dea5883afcc28473597f4df2493ccf1015e80967b2490cae5f41fb5dac9eb7925a2c9d00feeb9637b902366e3dc1be0d6dddc3c7ab
@@ -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
 
@@ -4,6 +4,7 @@ require_relative 'acts_as_recursive_tree/railtie' if defined?(Rails)
4
4
  module ActsAsRecursiveTree
5
5
  extend ActiveSupport::Autoload
6
6
 
7
+ autoload :Config
7
8
  autoload :ActsMacro
8
9
  autoload :Model
9
10
  autoload :Associations
@@ -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 = OpenStruct.new(
15
- primary_key: self.primary_key.to_sym,
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
- class_name: self.base_class.to_s,
21
- primary_key: self._recursive_tree_config.parent_key,
22
- foreign_key: self._recursive_tree_config.parent_key
20
+ through: :parent,
21
+ source: :children,
22
+ class_name: self.base_class.to_s
23
23
  end
24
24
  end
25
25
  end
@@ -5,6 +5,7 @@ module ActsAsRecursiveTree
5
5
  autoload :Values
6
6
  autoload :DepthCondition
7
7
  autoload :QueryOptions
8
+ autoload :Strategy
8
9
  autoload :RelationBuilder
9
10
  autoload :Descendants
10
11
  autoload :Ancestors
@@ -2,7 +2,7 @@ module ActsAsRecursiveTree
2
2
  module Builders
3
3
  class Leaves < Descendants
4
4
 
5
- def create_select_manger
5
+ def create_select_manger(column = nil)
6
6
  select_manager = super
7
7
 
8
8
  select_manager.where(
@@ -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
- final_select_mgr = base_table.join(
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
- travers_loc_table.project(Arel.star).with(:recursive, build_cte_table)
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
@@ -1,3 +1,3 @@
1
1
  module ActsAsRecursiveTree
2
- VERSION = '2.0.2'.freeze
2
+ VERSION = '2.1.0'.freeze
3
3
  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.2
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-02-06 00:00:00.000000000 Z
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.14
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: