acts_as_recursive_tree 2.1.1 → 3.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 +4 -4
- data/.github/workflows/ci.yml +44 -0
- data/.github/workflows/lint.yml +31 -0
- data/.github/workflows/rubygem.yml +37 -0
- data/.gitignore +3 -1
- data/.rubocop.yml +33 -1
- data/.rubocop_todo.yml +28 -281
- data/Appraisals +21 -0
- data/CHANGELOG.md +16 -1
- data/Gemfile +2 -0
- data/README.md +9 -0
- data/Rakefile +8 -8
- data/acts_as_recursive_tree.gemspec +27 -18
- data/gemfiles/ar_52.gemfile +8 -0
- data/gemfiles/ar_60.gemfile +8 -0
- data/gemfiles/ar_61.gemfile +8 -0
- data/gemfiles/ar_70.gemfile +8 -0
- data/lib/acts_as_recursive_tree/acts_macro.rb +6 -6
- data/lib/acts_as_recursive_tree/associations.rb +10 -8
- data/lib/acts_as_recursive_tree/builders/ancestors.rb +3 -2
- data/lib/acts_as_recursive_tree/builders/descendants.rb +3 -1
- data/lib/acts_as_recursive_tree/builders/leaves.rb +7 -8
- data/lib/acts_as_recursive_tree/builders/relation_builder.rb +14 -10
- data/lib/acts_as_recursive_tree/builders/{strategy → strategies}/ancestor.rb +3 -1
- data/lib/acts_as_recursive_tree/builders/{strategy → strategies}/descendant.rb +3 -1
- data/lib/acts_as_recursive_tree/builders/{strategy → strategies}/join.rb +5 -3
- data/lib/acts_as_recursive_tree/builders/{strategy → strategies}/subselect.rb +3 -1
- data/lib/acts_as_recursive_tree/builders/{strategy.rb → strategies.rb} +3 -9
- data/lib/acts_as_recursive_tree/config.rb +2 -0
- data/lib/acts_as_recursive_tree/model.rb +9 -8
- data/lib/acts_as_recursive_tree/options/depth_condition.rb +3 -2
- data/lib/acts_as_recursive_tree/options/query_options.rb +4 -2
- data/lib/acts_as_recursive_tree/options/values.rb +28 -18
- data/lib/acts_as_recursive_tree/railtie.rb +2 -0
- data/lib/acts_as_recursive_tree/scopes.rb +8 -4
- data/lib/acts_as_recursive_tree/version.rb +3 -1
- data/lib/acts_as_recursive_tree.rb +7 -11
- data/spec/builders_spec.rb +21 -12
- data/spec/db/database.rb +13 -4
- data/spec/db/database.yml +2 -5
- data/spec/db/models.rb +12 -11
- data/spec/db/schema.rb +3 -4
- data/spec/model/location_spec.rb +7 -11
- data/spec/model/node_spec.rb +35 -49
- data/spec/model/relation_spec.rb +6 -11
- data/spec/spec_helper.rb +54 -55
- data/spec/values_spec.rb +30 -19
- metadata +111 -26
- data/lib/acts_as_recursive_tree/builders.rb +0 -14
- data/lib/acts_as_recursive_tree/options.rb +0 -9
@@ -1,17 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActsAsRecursiveTree
|
2
4
|
module ActsMacro
|
3
|
-
|
4
5
|
##
|
5
6
|
# Configuration options are:
|
6
7
|
#
|
7
8
|
# * <tt>foreign_key</tt> - specifies the column name to use for tracking
|
8
9
|
# of the tree (default: +parent_id+)
|
9
10
|
def recursive_tree(parent_key: :parent_id, parent_type_column: nil)
|
10
|
-
|
11
11
|
class_attribute :_recursive_tree_config
|
12
12
|
self._recursive_tree_config = Config.new(
|
13
|
-
model_class:
|
14
|
-
parent_key:
|
13
|
+
model_class: self,
|
14
|
+
parent_key: parent_key.to_sym,
|
15
15
|
parent_type_column: parent_type_column.try(:to_sym)
|
16
16
|
)
|
17
17
|
|
@@ -20,6 +20,6 @@ module ActsAsRecursiveTree
|
|
20
20
|
include ActsAsRecursiveTree::Scopes
|
21
21
|
end
|
22
22
|
|
23
|
-
|
23
|
+
alias acts_as_tree recursive_tree
|
24
24
|
end
|
25
|
-
end
|
25
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'active_support/concern'
|
2
4
|
|
3
5
|
module ActsAsRecursiveTree
|
@@ -6,20 +8,20 @@ module ActsAsRecursiveTree
|
|
6
8
|
|
7
9
|
included do
|
8
10
|
belongs_to :parent,
|
9
|
-
class_name:
|
10
|
-
foreign_key:
|
11
|
-
inverse_of:
|
12
|
-
optional:
|
11
|
+
class_name: base_class.to_s,
|
12
|
+
foreign_key: _recursive_tree_config.parent_key,
|
13
|
+
inverse_of: :children,
|
14
|
+
optional: true
|
13
15
|
|
14
16
|
has_many :children,
|
15
|
-
class_name:
|
16
|
-
foreign_key:
|
17
|
-
inverse_of:
|
17
|
+
class_name: base_class.to_s,
|
18
|
+
foreign_key: _recursive_tree_config.parent_key,
|
19
|
+
inverse_of: :parent
|
18
20
|
|
19
21
|
has_many :self_and_siblings,
|
20
22
|
through: :parent,
|
21
23
|
source: :children,
|
22
|
-
class_name:
|
24
|
+
class_name: base_class.to_s
|
23
25
|
end
|
24
26
|
end
|
25
27
|
end
|
@@ -1,14 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActsAsRecursiveTree
|
2
4
|
module Builders
|
3
5
|
class Ancestors < RelationBuilder
|
4
|
-
self.traversal_strategy = ActsAsRecursiveTree::Builders::
|
6
|
+
self.traversal_strategy = ActsAsRecursiveTree::Builders::Strategies::Ancestor
|
5
7
|
|
6
8
|
def get_query_options(_)
|
7
9
|
opts = super
|
8
10
|
opts.ensure_ordering!
|
9
11
|
opts
|
10
12
|
end
|
11
|
-
|
12
13
|
end
|
13
14
|
end
|
14
15
|
end
|
@@ -1,7 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActsAsRecursiveTree
|
2
4
|
module Builders
|
3
5
|
class Descendants < RelationBuilder
|
4
|
-
self.traversal_strategy = ActsAsRecursiveTree::Builders::
|
6
|
+
self.traversal_strategy = ActsAsRecursiveTree::Builders::Strategies::Descendant
|
5
7
|
end
|
6
8
|
end
|
7
9
|
end
|
@@ -1,26 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActsAsRecursiveTree
|
2
4
|
module Builders
|
3
5
|
class Leaves < Descendants
|
4
|
-
|
5
6
|
def create_select_manger(column = nil)
|
6
7
|
select_manager = super
|
7
8
|
|
8
9
|
select_manager.where(
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
travers_loc_table[primary_key].not_in(
|
11
|
+
travers_loc_table.where(
|
12
|
+
travers_loc_table[parent_key].not_eq(nil)
|
13
|
+
).project(travers_loc_table[parent_key])
|
14
|
+
)
|
14
15
|
)
|
15
16
|
select_manager
|
16
|
-
|
17
17
|
end
|
18
18
|
|
19
19
|
def get_query_options(_)
|
20
20
|
# do not allow any custom options
|
21
21
|
ActsAsRecursiveTree::Options::QueryOptions.new
|
22
22
|
end
|
23
|
-
|
24
23
|
end
|
25
24
|
end
|
26
25
|
end
|
@@ -1,10 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActsAsRecursiveTree
|
2
4
|
module Builders
|
3
5
|
#
|
4
6
|
# Constructs the Arel necessary for recursion.
|
5
7
|
#
|
6
8
|
class RelationBuilder
|
7
|
-
|
8
9
|
def self.build(klass, ids, exclude_ids: false, &block)
|
9
10
|
new(klass, ids, exclude_ids: exclude_ids, &block).build
|
10
11
|
end
|
@@ -12,6 +13,7 @@ module ActsAsRecursiveTree
|
|
12
13
|
class_attribute :traversal_strategy, instance_writer: false
|
13
14
|
|
14
15
|
attr_reader :klass, :ids, :recursive_temp_table, :travers_loc_table, :without_ids
|
16
|
+
|
15
17
|
mattr_reader(:random) { Random.new }
|
16
18
|
|
17
19
|
# Delegators for easier accessing config and query options
|
@@ -41,7 +43,7 @@ module ActsAsRecursiveTree
|
|
41
43
|
def get_query_options(proc)
|
42
44
|
opts = ActsAsRecursiveTree::Options::QueryOptions.new
|
43
45
|
|
44
|
-
proc
|
46
|
+
proc&.call(opts)
|
45
47
|
|
46
48
|
opts
|
47
49
|
end
|
@@ -51,14 +53,14 @@ module ActsAsRecursiveTree
|
|
51
53
|
end
|
52
54
|
|
53
55
|
def build
|
54
|
-
relation =
|
56
|
+
relation = Strategies.for_query_options(@query_opts).build(self)
|
55
57
|
|
56
|
-
|
57
|
-
relation
|
58
|
+
apply_except_id(relation)
|
58
59
|
end
|
59
60
|
|
60
61
|
def apply_except_id(relation)
|
61
62
|
return relation unless without_ids
|
63
|
+
|
62
64
|
relation.where(ids.apply_negated_to(base_table[primary_key]))
|
63
65
|
end
|
64
66
|
|
@@ -70,10 +72,10 @@ module ActsAsRecursiveTree
|
|
70
72
|
|
71
73
|
def create_select_manger(column = nil)
|
72
74
|
projections = if column
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
75
|
+
travers_loc_table[column]
|
76
|
+
else
|
77
|
+
Arel.star
|
78
|
+
end
|
77
79
|
|
78
80
|
select_mgr = travers_loc_table.project(projections).with(:recursive, build_cte_table)
|
79
81
|
|
@@ -114,7 +116,8 @@ module ActsAsRecursiveTree
|
|
114
116
|
end
|
115
117
|
|
116
118
|
def apply_parent_type_column(arel_condition)
|
117
|
-
return arel_condition
|
119
|
+
return arel_condition if parent_type_column.blank?
|
120
|
+
|
118
121
|
arel_condition.and(base_table[parent_type_column].eq(klass.base_class))
|
119
122
|
end
|
120
123
|
|
@@ -131,6 +134,7 @@ module ActsAsRecursiveTree
|
|
131
134
|
def apply_query_opts_condition(relation)
|
132
135
|
# check with nil? and not #present?/#blank? which will execute the query
|
133
136
|
return relation if condition.nil?
|
137
|
+
|
134
138
|
relation.merge(condition)
|
135
139
|
end
|
136
140
|
end
|
@@ -1,6 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActsAsRecursiveTree
|
2
4
|
module Builders
|
3
|
-
module
|
5
|
+
module Strategies
|
4
6
|
#
|
5
7
|
# Build a relation using an INNER JOIN.
|
6
8
|
#
|
@@ -19,12 +21,12 @@ module ActsAsRecursiveTree
|
|
19
21
|
|
20
22
|
relation = builder.klass.joins(final_select_mgr.join_sources)
|
21
23
|
|
22
|
-
|
23
|
-
relation
|
24
|
+
apply_order(builder, relation)
|
24
25
|
end
|
25
26
|
|
26
27
|
def self.apply_order(builder, relation)
|
27
28
|
return relation unless builder.ensure_ordering
|
29
|
+
|
28
30
|
relation.order(builder.recursive_temp_table[builder.depth_column].asc)
|
29
31
|
end
|
30
32
|
end
|
@@ -1,17 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActsAsRecursiveTree
|
2
4
|
module Builders
|
3
5
|
#
|
4
6
|
# Strategy module for different strategies of how to build the resulting query.
|
5
7
|
#
|
6
|
-
module
|
7
|
-
extend ActiveSupport::Autoload
|
8
|
-
|
9
|
-
autoload :Join
|
10
|
-
autoload :Subselect
|
11
|
-
|
12
|
-
autoload :Descendant
|
13
|
-
autoload :Ancestor
|
14
|
-
|
8
|
+
module Strategies
|
15
9
|
#
|
16
10
|
# Returns a Strategy appropriate for query_opts
|
17
11
|
#
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActsAsRecursiveTree
|
2
4
|
module Model
|
3
5
|
extend ActiveSupport::Concern
|
@@ -40,7 +42,7 @@ module ActsAsRecursiveTree
|
|
40
42
|
##
|
41
43
|
# Returns the root node of the tree.
|
42
44
|
def root
|
43
|
-
self_and_ancestors.where(
|
45
|
+
self_and_ancestors.where(_recursive_tree_config.parent_key => nil).first
|
44
46
|
end
|
45
47
|
|
46
48
|
##
|
@@ -48,7 +50,7 @@ module ActsAsRecursiveTree
|
|
48
50
|
#
|
49
51
|
# subchild1.siblings # => [subchild2]
|
50
52
|
def siblings
|
51
|
-
self_and_siblings.where.not(id:
|
53
|
+
self_and_siblings.where.not(id: id)
|
52
54
|
end
|
53
55
|
|
54
56
|
##
|
@@ -57,11 +59,11 @@ module ActsAsRecursiveTree
|
|
57
59
|
# root.self_and_children # => [root, child1]
|
58
60
|
def self_and_children
|
59
61
|
table = self.class.arel_table
|
60
|
-
id =
|
62
|
+
id = attributes[_recursive_tree_config.primary_key.to_s]
|
61
63
|
|
62
64
|
base_class.where(
|
63
|
-
table[
|
64
|
-
table[
|
65
|
+
table[_recursive_tree_config.primary_key].eq(id).or(
|
66
|
+
table[_recursive_tree_config.parent_key].eq(id)
|
65
67
|
)
|
66
68
|
)
|
67
69
|
end
|
@@ -73,13 +75,12 @@ module ActsAsRecursiveTree
|
|
73
75
|
base_class.leaves_of(self)
|
74
76
|
end
|
75
77
|
|
76
|
-
|
77
78
|
# Returns true if node has no parent, false otherwise
|
78
79
|
#
|
79
80
|
# subchild1.root? # => false
|
80
81
|
# root.root? # => true
|
81
82
|
def root?
|
82
|
-
|
83
|
+
attributes[_recursive_tree_config.parent_key.to_s].blank?
|
83
84
|
end
|
84
85
|
|
85
86
|
# Returns true if node has no children, false otherwise
|
@@ -87,7 +88,7 @@ module ActsAsRecursiveTree
|
|
87
88
|
# subchild1.leaf? # => true
|
88
89
|
# child1.leaf? # => false
|
89
90
|
def leaf?
|
90
|
-
|
91
|
+
children.none?
|
91
92
|
end
|
92
93
|
|
93
94
|
def base_class
|
@@ -1,8 +1,9 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActsAsRecursiveTree
|
2
4
|
module Options
|
3
5
|
class QueryOptions
|
4
|
-
|
5
|
-
STRATEGIES = %i[subselect, join].freeze
|
6
|
+
STRATEGIES = %i[subselect join].freeze
|
6
7
|
|
7
8
|
attr_accessor :condition
|
8
9
|
attr_reader :ensure_ordering, :query_strategy
|
@@ -21,6 +22,7 @@ module ActsAsRecursiveTree
|
|
21
22
|
|
22
23
|
def query_strategy=(strategy)
|
23
24
|
raise "invalid strategy #{strategy} - only #{STRATEGIES} are allowed" unless STRATEGIES.include?(strategy)
|
25
|
+
|
24
26
|
@query_strategy = strategy
|
25
27
|
end
|
26
28
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActsAsRecursiveTree
|
2
4
|
module Options
|
3
5
|
module Values
|
@@ -13,13 +15,9 @@ module ActsAsRecursiveTree
|
|
13
15
|
value
|
14
16
|
end
|
15
17
|
|
16
|
-
def apply_to(attribute)
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
def apply_negated_to(attribute)
|
18
|
+
def apply_to(attribute); end
|
21
19
|
|
22
|
-
end
|
20
|
+
def apply_negated_to(attribute); end
|
23
21
|
end
|
24
22
|
|
25
23
|
class SingleValue < Base
|
@@ -38,6 +36,16 @@ module ActsAsRecursiveTree
|
|
38
36
|
end
|
39
37
|
end
|
40
38
|
|
39
|
+
class RangeValue < Base
|
40
|
+
def apply_to(attribute)
|
41
|
+
attribute.between(prepared_value)
|
42
|
+
end
|
43
|
+
|
44
|
+
def apply_negated_to(attribute)
|
45
|
+
attribute.not_between(prepared_value)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
41
49
|
class MultiValue < Base
|
42
50
|
def apply_to(attribute)
|
43
51
|
attribute.in(prepared_value)
|
@@ -58,20 +66,22 @@ module ActsAsRecursiveTree
|
|
58
66
|
|
59
67
|
def self.create(value, config = nil)
|
60
68
|
klass = case value
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
69
|
+
when ::Numeric, ::String
|
70
|
+
SingleValue
|
71
|
+
when ::ActiveRecord::Relation
|
72
|
+
Relation
|
73
|
+
when Range
|
74
|
+
RangeValue
|
75
|
+
when Enumerable
|
76
|
+
MultiValue
|
77
|
+
when ::ActiveRecord::Base
|
78
|
+
ActiveRecord
|
79
|
+
else
|
80
|
+
raise "#{value.class} is not supported"
|
81
|
+
end
|
72
82
|
|
73
83
|
klass.new(value, config)
|
74
84
|
end
|
75
85
|
end
|
76
86
|
end
|
77
|
-
end
|
87
|
+
end
|
@@ -1,13 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module ActsAsRecursiveTree
|
2
4
|
module Scopes
|
3
5
|
extend ActiveSupport::Concern
|
4
6
|
|
5
7
|
included do
|
6
|
-
scope :roots,
|
8
|
+
scope :roots, lambda {
|
7
9
|
rel = where(_recursive_tree_config.parent_key => nil)
|
8
|
-
|
9
|
-
|
10
|
-
|
10
|
+
if _recursive_tree_config.parent_type_column
|
11
|
+
rel = rel.or(
|
12
|
+
where.not(_recursive_tree_config.parent_type_column => to_s)
|
13
|
+
)
|
14
|
+
end
|
11
15
|
|
12
16
|
rel
|
13
17
|
}
|
@@ -1,15 +1,11 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require_relative 'acts_as_recursive_tree/railtie' if defined?(Rails)
|
4
|
+
require 'zeitwerk'
|
3
5
|
|
4
|
-
|
5
|
-
|
6
|
+
loader = Zeitwerk::Loader.for_gem
|
7
|
+
loader.setup
|
6
8
|
|
7
|
-
|
8
|
-
|
9
|
-
autoload :Model
|
10
|
-
autoload :Associations
|
11
|
-
autoload :Scopes
|
12
|
-
autoload :Version
|
13
|
-
autoload :Options
|
14
|
-
autoload :Builders
|
9
|
+
module ActsAsRecursiveTree
|
10
|
+
# nothing special here
|
15
11
|
end
|
data/spec/builders_spec.rb
CHANGED
@@ -1,13 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
3
5
|
shared_context 'setup with enforced ordering' do
|
4
6
|
let(:ordering) { false }
|
5
7
|
include_context 'base_setup' do
|
6
|
-
let(:proc) { ->
|
8
|
+
let(:proc) { ->(config) { config.ensure_ordering! } }
|
7
9
|
end
|
8
10
|
end
|
9
11
|
|
10
12
|
shared_context 'base_setup' do
|
13
|
+
subject(:query) { builder.build.to_sql }
|
14
|
+
|
11
15
|
let(:model_id) { 1 }
|
12
16
|
let(:model_class) { Node }
|
13
17
|
let(:exclude_ids) { false }
|
@@ -15,17 +19,20 @@ shared_context 'base_setup' do
|
|
15
19
|
let(:builder) do
|
16
20
|
described_class.new(model_class, model_id, exclude_ids: exclude_ids, &proc)
|
17
21
|
end
|
18
|
-
subject(:query) { builder.build.to_sql }
|
19
22
|
end
|
20
23
|
|
21
24
|
shared_examples 'basic recursive examples' do
|
22
25
|
it { is_expected.to start_with "SELECT \"#{model_class.table_name}\".* FROM \"#{model_class.table_name}\"" }
|
23
|
-
|
24
|
-
it { is_expected.to match
|
25
|
-
|
26
|
-
it { is_expected.to match
|
27
|
-
|
28
|
-
it { is_expected.to match
|
26
|
+
|
27
|
+
it { is_expected.to match(/WHERE "#{model_class.table_name}"."#{model_class.primary_key}" = #{model_id}/) }
|
28
|
+
|
29
|
+
it { is_expected.to match(/WITH RECURSIVE "#{builder.travers_loc_table.name}" AS/) }
|
30
|
+
|
31
|
+
it { is_expected.to match(/SELECT "#{model_class.table_name}"."#{model_class.primary_key}", "#{model_class.table_name}"."#{model_class._recursive_tree_config.parent_key}", 0 AS recursive_depth FROM "#{model_class.table_name}"/) }
|
32
|
+
|
33
|
+
it {
|
34
|
+
expect(subject).to match(/SELECT "#{model_class.table_name}"."#{model_class.primary_key}", "#{model_class.table_name}"."#{model_class._recursive_tree_config.parent_key}", \("#{builder.travers_loc_table.name}"."recursive_depth" \+ 1\) AS recursive_depth FROM "#{model_class.table_name}"/)
|
35
|
+
}
|
29
36
|
end
|
30
37
|
|
31
38
|
shared_examples 'build recursive query' do
|
@@ -63,13 +70,14 @@ end
|
|
63
70
|
shared_examples 'ancestor query' do
|
64
71
|
include_context 'base_setup'
|
65
72
|
|
66
|
-
it { is_expected.to match
|
73
|
+
it { is_expected.to match(/"#{builder.travers_loc_table.name}"."#{model_class._recursive_tree_config.parent_key}" = "#{model_class.table_name}"."#{model_class.primary_key}"/) }
|
67
74
|
end
|
68
75
|
|
69
76
|
shared_examples 'descendant query' do
|
70
77
|
include_context 'base_setup'
|
71
78
|
|
72
|
-
it { is_expected.to match
|
79
|
+
it { is_expected.to match(/"#{model_class.table_name}"."#{model_class._recursive_tree_config.parent_key}" = "#{builder.travers_loc_table.name}"."#{model_class.primary_key}"/) }
|
80
|
+
it { is_expected.to match(/#{Regexp.escape(builder.travers_loc_table.project(builder.travers_loc_table[model_class.primary_key]).to_sql)}/) }
|
73
81
|
end
|
74
82
|
|
75
83
|
shared_context 'context with ordering' do
|
@@ -85,11 +93,11 @@ shared_context 'context without ordering' do
|
|
85
93
|
end
|
86
94
|
|
87
95
|
shared_examples 'with ordering' do
|
88
|
-
it { is_expected.to match
|
96
|
+
it { is_expected.to match(/ORDER BY #{Regexp.escape(builder.recursive_temp_table[model_class._recursive_tree_config.depth_column].asc.to_sql)}/) }
|
89
97
|
end
|
90
98
|
|
91
99
|
shared_examples 'without ordering' do
|
92
|
-
it { is_expected.
|
100
|
+
it { is_expected.not_to match(/ORDER BY/) }
|
93
101
|
end
|
94
102
|
|
95
103
|
describe ActsAsRecursiveTree::Builders::Descendants do
|
@@ -113,6 +121,7 @@ describe ActsAsRecursiveTree::Builders::Ancestors do
|
|
113
121
|
it_behaves_like 'ancestor query'
|
114
122
|
include_context 'context with ordering'
|
115
123
|
end
|
124
|
+
|
116
125
|
context 'with options' do
|
117
126
|
include_context 'setup with enforced ordering' do
|
118
127
|
it_behaves_like 'with ordering'
|