active_record_extended 1.4.0 → 2.0.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/README.md +8 -7
- data/lib/active_record_extended/active_record.rb +1 -10
- data/lib/active_record_extended/active_record/relation_patch.rb +16 -1
- data/lib/active_record_extended/arel.rb +1 -0
- data/lib/active_record_extended/arel/nodes.rb +22 -21
- data/lib/active_record_extended/arel/sql_literal.rb +16 -0
- data/lib/active_record_extended/query_methods/any_of.rb +5 -4
- data/lib/active_record_extended/query_methods/either.rb +1 -1
- data/lib/active_record_extended/query_methods/inet.rb +6 -2
- data/lib/active_record_extended/query_methods/json.rb +13 -16
- data/lib/active_record_extended/query_methods/select.rb +11 -10
- data/lib/active_record_extended/query_methods/unionize.rb +10 -4
- data/lib/active_record_extended/query_methods/where_chain.rb +14 -6
- data/lib/active_record_extended/query_methods/window.rb +4 -3
- data/lib/active_record_extended/query_methods/with_cte.rb +102 -35
- data/lib/active_record_extended/utilities/order_by.rb +9 -28
- data/lib/active_record_extended/utilities/support.rb +8 -15
- data/lib/active_record_extended/version.rb +1 -1
- data/spec/query_methods/any_of_spec.rb +2 -2
- data/spec/query_methods/json_spec.rb +5 -5
- data/spec/query_methods/select_spec.rb +13 -13
- data/spec/query_methods/unionize_spec.rb +5 -5
- data/spec/query_methods/with_cte_spec.rb +12 -2
- data/spec/spec_helper.rb +1 -1
- data/spec/sql_inspections/any_of_sql_spec.rb +2 -2
- data/spec/sql_inspections/contains_sql_queries_spec.rb +8 -8
- data/spec/sql_inspections/either_sql_spec.rb +3 -3
- data/spec/sql_inspections/json_sql_spec.rb +0 -1
- data/spec/sql_inspections/unionize_sql_spec.rb +2 -2
- data/spec/sql_inspections/window_sql_spec.rb +12 -0
- data/spec/sql_inspections/with_cte_sql_spec.rb +30 -1
- metadata +18 -20
- data/lib/active_record_extended/patch/5_0/predicate_builder_decorator.rb +0 -87
- data/lib/active_record_extended/patch/5_0/regex_match.rb +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9934d5a90324b46dc3faa7b496724ac219a2582d264db89e64e2b9be574adab6
|
4
|
+
data.tar.gz: c1359988f9a6b83148f36548e842a25cab68a191e7a839caef7e783b1415b346
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e7385b414ef4c8d8b0c5b29eaeb70e77ba79f07828255deef5db79e99cf33f18de7bab696501711dee1f8e056ca3bdf628cdd498b341a91b5ad5cd2c766bd61c
|
7
|
+
data.tar.gz: 10e8d4f65c570dba757b2cf47aaaff7f8a5538974e9c8aadb3c267e3e3fccb9508b05a8722eb5d6680937cb15827f6fa4f88d6dd219d8240c58323385fe44eb2
|
data/README.md
CHANGED
@@ -52,11 +52,12 @@ Active Record Extended is essentially providing users with the other half of Pos
|
|
52
52
|
## Compatibility
|
53
53
|
|
54
54
|
This package is designed align and work with any officially supported Ruby and Rails versions.
|
55
|
-
- Minimum Ruby Version: 2.
|
56
|
-
- Minimum Rails Version: 5.
|
57
|
-
-
|
58
|
-
- Latest
|
59
|
-
-
|
55
|
+
- Minimum Ruby Version: 2.4.x **(EOL warning!)**
|
56
|
+
- Minimum Rails Version: 5.1.x **(EOL warning!)**
|
57
|
+
- Minimum Postgres Version: 9.6.x **(EOL warning!)**
|
58
|
+
- Latest Ruby supported: 2.7.x
|
59
|
+
- Latest Rails supported: 6.1.x
|
60
|
+
- Postgres: 9.6-current(13) (probably works with most older versions to a certain point)
|
60
61
|
|
61
62
|
## Installation
|
62
63
|
|
@@ -430,7 +431,7 @@ While quite the mouthful of an explanation. The implementation of combining unre
|
|
430
431
|
product_query =
|
431
432
|
Product.select(:id)
|
432
433
|
.joins(:items)
|
433
|
-
.select_row_to_json(item_query, key: :outer_items, as: :items,
|
434
|
+
.select_row_to_json(item_query, key: :outer_items, as: :items, cast_with: :array) do |item_scope|
|
434
435
|
item_scope.where("outer_items.product_id = products.id")
|
435
436
|
# Results to:
|
436
437
|
# SELECT ..., ARRAY(SELECT ROW_TO_JSON("outer_items")
|
@@ -440,7 +441,7 @@ While quite the mouthful of an explanation. The implementation of combining unre
|
|
440
441
|
end
|
441
442
|
|
442
443
|
# Not defining a key will automatically generate a random key between a-z
|
443
|
-
category_query = Category.select(:name, :id).select_row_to_json(product_query, as: :products,
|
444
|
+
category_query = Category.select(:name, :id).select_row_to_json(product_query, as: :products, cast_with: :array)
|
444
445
|
Category.json_build_object(:physical_category, category_query.where(id: physical_cat.id)).results
|
445
446
|
#=> {
|
446
447
|
# "physical_category" => {
|
@@ -1,10 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# TODO: Remove this when ruby 2.3 support is dropped
|
4
|
-
unless Hash.instance_methods(false).include?(:compact!)
|
5
|
-
require "active_support/all"
|
6
|
-
end
|
7
|
-
|
8
3
|
require "active_record"
|
9
4
|
require "active_record/relation"
|
10
5
|
require "active_record/relation/merger"
|
@@ -23,11 +18,7 @@ require "active_record_extended/query_methods/inet"
|
|
23
18
|
require "active_record_extended/query_methods/json"
|
24
19
|
require "active_record_extended/query_methods/select"
|
25
20
|
|
26
|
-
if ActiveRecord::VERSION::MAJOR == 5 && ActiveRecord::VERSION::MINOR
|
27
|
-
if ActiveRecord::VERSION::MINOR.zero?
|
28
|
-
require "active_record_extended/patch/5_0/regex_match"
|
29
|
-
require "active_record_extended/patch/5_0/predicate_builder_decorator"
|
30
|
-
end
|
21
|
+
if ActiveRecord::VERSION::MAJOR == 5 && ActiveRecord::VERSION::MINOR == 1
|
31
22
|
require "active_record_extended/patch/5_1/where_clause"
|
32
23
|
elsif ActiveRecord::VERSION::MAJOR >= 5
|
33
24
|
require "active_record_extended/patch/5_2/where_clause"
|
@@ -14,7 +14,22 @@ module ActiveRecordExtended
|
|
14
14
|
|
15
15
|
module Merger
|
16
16
|
def normal_values
|
17
|
-
super + [:
|
17
|
+
super + [:union, :define_window]
|
18
|
+
end
|
19
|
+
|
20
|
+
def merge
|
21
|
+
merge_ctes!
|
22
|
+
super
|
23
|
+
end
|
24
|
+
|
25
|
+
def merge_ctes!
|
26
|
+
return unless other.with_values?
|
27
|
+
|
28
|
+
if other.recursive_value? && !relation.recursive_value?
|
29
|
+
relation.with!(:chain).recursive(other.cte)
|
30
|
+
else
|
31
|
+
relation.with!(other.cte)
|
32
|
+
end
|
18
33
|
end
|
19
34
|
end
|
20
35
|
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "active_record_extended/arel/nodes"
|
4
|
+
require "active_record_extended/arel/sql_literal"
|
4
5
|
require "active_record_extended/arel/aggregate_function_name"
|
5
6
|
require "active_record_extended/arel/predications"
|
6
7
|
require "active_record_extended/arel/visitors/postgresql_decorator"
|
@@ -5,28 +5,29 @@ require "arel/nodes/function"
|
|
5
5
|
|
6
6
|
module Arel
|
7
7
|
module Nodes
|
8
|
-
|
9
|
-
Overlap
|
10
|
-
Contains
|
11
|
-
ContainsHStore
|
12
|
-
ContainsArray
|
13
|
-
ContainedInArray
|
8
|
+
[
|
9
|
+
"Overlap",
|
10
|
+
"Contains",
|
11
|
+
"ContainsHStore",
|
12
|
+
"ContainsArray",
|
13
|
+
"ContainedInArray"
|
14
14
|
].each { |binary_node_name| const_set(binary_node_name, Class.new(::Arel::Nodes::Binary)) }
|
15
15
|
|
16
|
-
|
17
|
-
RowToJson
|
18
|
-
JsonBuildObject
|
19
|
-
JsonbBuildObject
|
20
|
-
ToJson
|
21
|
-
ToJsonb
|
22
|
-
Array
|
23
|
-
ArrayAgg
|
16
|
+
[
|
17
|
+
"RowToJson",
|
18
|
+
"JsonBuildObject",
|
19
|
+
"JsonbBuildObject",
|
20
|
+
"ToJson",
|
21
|
+
"ToJsonb",
|
22
|
+
"Array",
|
23
|
+
"ArrayAgg"
|
24
24
|
].each do |function_node_name|
|
25
25
|
func_klass = Class.new(::Arel::Nodes::Function) do
|
26
26
|
def initialize(*args)
|
27
27
|
super
|
28
28
|
return if @expressions.is_a?(::Array)
|
29
|
-
|
29
|
+
|
30
|
+
@expressions = @expressions.is_a?(::Arel::Nodes::Node) ? [@expressions] : [::Arel.sql(@expressions)]
|
30
31
|
end
|
31
32
|
end
|
32
33
|
|
@@ -34,12 +35,12 @@ module Arel
|
|
34
35
|
end
|
35
36
|
|
36
37
|
module Inet
|
37
|
-
|
38
|
-
Contains
|
39
|
-
ContainsEquals
|
40
|
-
ContainedWithin
|
41
|
-
ContainedWithinEquals
|
42
|
-
ContainsOrContainedWithin
|
38
|
+
[
|
39
|
+
"Contains",
|
40
|
+
"ContainsEquals",
|
41
|
+
"ContainedWithin",
|
42
|
+
"ContainedWithinEquals",
|
43
|
+
"ContainsOrContainedWithin"
|
43
44
|
].each { |binary_node_name| const_set(binary_node_name, Class.new(::Arel::Nodes::Binary)) }
|
44
45
|
end
|
45
46
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "arel/nodes/sql_literal"
|
4
|
+
|
5
|
+
# CTE alias fix for Rails 6.1
|
6
|
+
module Arel
|
7
|
+
module Nodes
|
8
|
+
module SqlLiteralDecorator
|
9
|
+
def name
|
10
|
+
self
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
Arel::Nodes::SqlLiteral.prepend(Arel::Nodes::SqlLiteralDecorator)
|
@@ -61,13 +61,14 @@ module ActiveRecordExtended
|
|
61
61
|
# In Rails 5.2 the arel table maintains attribute binds
|
62
62
|
def bind_attributes(query)
|
63
63
|
return [] unless query.respond_to?(:bound_attributes)
|
64
|
+
|
64
65
|
query.bound_attributes.map(&:value)
|
65
66
|
end
|
66
67
|
|
67
68
|
# Rails 5.1 fix
|
68
69
|
def unprepared_query(query)
|
69
|
-
query.gsub(/((?<!\\)'.*?(?<!\\)'|(?<!\\)".*?(?<!\\)")|(
|
70
|
-
Regexp.last_match(2)&.gsub(
|
70
|
+
query.gsub(/((?<!\\)'.*?(?<!\\)'|(?<!\\)".*?(?<!\\)")|(=\ \$\d+)/) do |match|
|
71
|
+
Regexp.last_match(2)&.gsub(/=\ \$\d+/, "= ?") || match
|
71
72
|
end
|
72
73
|
end
|
73
74
|
|
@@ -78,9 +79,9 @@ module ActiveRecordExtended
|
|
78
79
|
def generate_where_clause(query)
|
79
80
|
case query
|
80
81
|
when String, Hash
|
81
|
-
@scope.where(query)
|
82
|
+
@scope.unscoped.where(query)
|
82
83
|
when Array
|
83
|
-
@scope.where(*query)
|
84
|
+
@scope.unscoped.where(*query)
|
84
85
|
else
|
85
86
|
query
|
86
87
|
end
|
@@ -74,8 +74,12 @@ module ActiveRecordExtended
|
|
74
74
|
# #=> "SELECT \"users\".* FROM \"users\" WHERE \"users\".\"ip\" && '127.0.0.255/32'"
|
75
75
|
#
|
76
76
|
def inet_contains_or_is_contained_within(opts, *rest)
|
77
|
-
substitute_comparisons(
|
78
|
-
|
77
|
+
substitute_comparisons(
|
78
|
+
opts,
|
79
|
+
rest,
|
80
|
+
Arel::Nodes::Inet::ContainsOrContainedWithin,
|
81
|
+
"inet_contains_or_is_contained_within"
|
82
|
+
)
|
79
83
|
end
|
80
84
|
end
|
81
85
|
end
|
@@ -8,7 +8,7 @@ module ActiveRecordExtended
|
|
8
8
|
:json_build_object,
|
9
9
|
:jsonb_build_object,
|
10
10
|
:json_build_literal,
|
11
|
-
:jsonb_build_literal
|
11
|
+
:jsonb_build_literal
|
12
12
|
].freeze
|
13
13
|
|
14
14
|
class JsonChain
|
@@ -77,7 +77,7 @@ module ActiveRecordExtended
|
|
77
77
|
row_to_json = ::Arel::Nodes::ToJsonb.new(row_to_json) if options.dig(:cast_with, :to_jsonb)
|
78
78
|
|
79
79
|
dummy_table = from_clause_constructor(from, key).select(row_to_json)
|
80
|
-
dummy_table = dummy_table.instance_eval(&block) if
|
80
|
+
dummy_table = dummy_table.instance_eval(&block) if block
|
81
81
|
return dummy_table if options[:col_alias].blank?
|
82
82
|
|
83
83
|
query = wrap_row_to_json(dummy_table, options)
|
@@ -98,7 +98,6 @@ module ActiveRecordExtended
|
|
98
98
|
end
|
99
99
|
end
|
100
100
|
|
101
|
-
# TODO: [V2 release] Drop support for option :cast_as_array in favor of a more versatile :cast_with option
|
102
101
|
def json_object_options(args, except: [], only: []) # rubocop:disable Metrics/AbcSize, Metrics/PerceivedComplexity
|
103
102
|
options = {}
|
104
103
|
lean_opts = lambda do |key, &block|
|
@@ -113,12 +112,12 @@ module ActiveRecordExtended
|
|
113
112
|
next if arg.nil?
|
114
113
|
|
115
114
|
if arg.is_a?(Hash)
|
116
|
-
lean_opts.call(:key) { arg.
|
117
|
-
lean_opts.call(:value) { arg
|
118
|
-
lean_opts.call(:col_alias) { arg
|
119
|
-
lean_opts.call(:order_by) { order_by_expression(arg
|
120
|
-
lean_opts.call(:from) { arg
|
121
|
-
lean_opts.call(:cast_with) { casting_options(arg
|
115
|
+
lean_opts.call(:key) { arg.fetch(:key, key_generator) }
|
116
|
+
lean_opts.call(:value) { arg[:value].presence }
|
117
|
+
lean_opts.call(:col_alias) { arg[:as] }
|
118
|
+
lean_opts.call(:order_by) { order_by_expression(arg[:order_by]) }
|
119
|
+
lean_opts.call(:from) { arg[:from].tap { |from_clause| pipe_cte_with!(from_clause) } }
|
120
|
+
lean_opts.call(:cast_with) { casting_options(arg[:cast_with]) }
|
122
121
|
end
|
123
122
|
|
124
123
|
unless except.include?(:values)
|
@@ -155,9 +154,6 @@ module ActiveRecordExtended
|
|
155
154
|
# - key: [Symbol or String] (default=[random letter]) What the row clause will be set as.
|
156
155
|
# - This is useful if you would like to add additional mid-level clauses (see mid-level scope example)
|
157
156
|
#
|
158
|
-
# - cast_as_array [boolean] (default=false): Determines if the query should be nested inside an Array() function
|
159
|
-
# * Will be deprecated in V2.0 in favor of `cast_with` argument
|
160
|
-
#
|
161
157
|
# - cast_with [Symbol or Array of symbols]: Actions to transform your query
|
162
158
|
# * :to_jsonb
|
163
159
|
# * :array
|
@@ -172,13 +168,13 @@ module ActiveRecordExtended
|
|
172
168
|
#
|
173
169
|
# Examples:
|
174
170
|
# subquery = Group.select(:name, :category_id).where("user_id = users.id")
|
175
|
-
# User.select(:name, email).select_row_to_json(subquery, as: :users_groups,
|
171
|
+
# User.select(:name, email).select_row_to_json(subquery, as: :users_groups, cast_with: :array)
|
176
172
|
# #=> [<#User name:.., email:.., users_groups: [{ name: .., category_id: .. }, ..]]
|
177
173
|
#
|
178
174
|
# - Adding mid-level scopes:
|
179
175
|
#
|
180
176
|
# subquery = Group.select(:name, :category_id)
|
181
|
-
# User.select_row_to_json(subquery, key: :group,
|
177
|
+
# User.select_row_to_json(subquery, key: :group, cast_with: :array) do |scope|
|
182
178
|
# scope.where(group: { name: "Nerd Core" })
|
183
179
|
# end
|
184
180
|
# #=> ```sql
|
@@ -252,7 +248,8 @@ module ActiveRecordExtended
|
|
252
248
|
def select_row_to_json(from = nil, **options, &block)
|
253
249
|
from.is_a?(Hash) ? options.merge!(from) : options.reverse_merge!(from: from)
|
254
250
|
options.compact!
|
255
|
-
raise ArgumentError
|
251
|
+
raise ArgumentError.new("Required to provide a non-nilled from clause") unless options.key?(:from)
|
252
|
+
|
256
253
|
JsonChain.new(spawn).row_to_json!(**options, &block)
|
257
254
|
end
|
258
255
|
|
@@ -273,7 +270,7 @@ module ActiveRecordExtended
|
|
273
270
|
# - Generic example:
|
274
271
|
#
|
275
272
|
# subquery = Group.select(:name, :category_id).where("user_id = users.id")
|
276
|
-
# User.select(:name, email).select_row_to_json(subquery, as: :users_groups,
|
273
|
+
# User.select(:name, email).select_row_to_json(subquery, as: :users_groups, cast_with: :array)
|
277
274
|
# #=> [<#User name:.., email:.., users_groups: [{ name: .., category_id: .. }, ..]]
|
278
275
|
#
|
279
276
|
# - Setting a custom value:
|
@@ -52,12 +52,12 @@ module ActiveRecordExtended
|
|
52
52
|
# #=> SELECT (ARRAY_AGG(DISTINCT members.price)) AS past_purchases, ...
|
53
53
|
def process_hash!(hash_of_options, alias_name)
|
54
54
|
enforced_options = {
|
55
|
-
cast_with: hash_of_options
|
56
|
-
order_by: hash_of_options
|
57
|
-
distinct: !(!hash_of_options
|
55
|
+
cast_with: hash_of_options[:cast_with],
|
56
|
+
order_by: hash_of_options[:order_by],
|
57
|
+
distinct: !(!hash_of_options[:distinct])
|
58
58
|
}
|
59
|
-
query_statement = hash_to_dot_notation(hash_of_options
|
60
|
-
select!(query_statement, alias_name, enforced_options)
|
59
|
+
query_statement = hash_to_dot_notation(hash_of_options[:__select_statement] || hash_of_options.first)
|
60
|
+
select!(query_statement, alias_name, **enforced_options)
|
61
61
|
end
|
62
62
|
|
63
63
|
# Turn a hash chain into a query statement:
|
@@ -76,7 +76,7 @@ module ActiveRecordExtended
|
|
76
76
|
# Add's select statement values to the current relation, select statement lists
|
77
77
|
def select!(query, alias_name = nil, **options)
|
78
78
|
pipe_cte_with!(query)
|
79
|
-
@scope._select!(to_casted_query(query, alias_name, options))
|
79
|
+
@scope._select!(to_casted_query(query, alias_name, **options))
|
80
80
|
end
|
81
81
|
|
82
82
|
# Wraps the query with the requested query method
|
@@ -84,9 +84,9 @@ module ActiveRecordExtended
|
|
84
84
|
# to_casted_query("memberships.cost", :total_revenue, :sum)
|
85
85
|
# #=> SELECT (SUM(memberships.cost)) AS total_revenue
|
86
86
|
def to_casted_query(query, alias_name, **options)
|
87
|
-
cast_with = options
|
88
|
-
order_expr = order_by_expression(options
|
89
|
-
distinct = cast_with.chomp!("_distinct") || options
|
87
|
+
cast_with = options[:cast_with].to_s.downcase
|
88
|
+
order_expr = order_by_expression(options[:order_by])
|
89
|
+
distinct = cast_with.chomp!("_distinct") || options[:distinct] # account for [:agg_name:]_distinct
|
90
90
|
|
91
91
|
case cast_with
|
92
92
|
when "array", "true"
|
@@ -102,7 +102,8 @@ module ActiveRecordExtended
|
|
102
102
|
end
|
103
103
|
|
104
104
|
def foster_select(*args)
|
105
|
-
raise ArgumentError
|
105
|
+
raise ArgumentError.new("Call `.forster_select' with at least one field") if args.empty?
|
106
|
+
|
106
107
|
spawn._foster_select!(*args)
|
107
108
|
end
|
108
109
|
|
@@ -81,7 +81,7 @@ module ActiveRecordExtended
|
|
81
81
|
union_values: [],
|
82
82
|
union_operations: [],
|
83
83
|
union_ordering_values: [],
|
84
|
-
unionized_name: nil
|
84
|
+
unionized_name: nil
|
85
85
|
}
|
86
86
|
end
|
87
87
|
|
@@ -89,10 +89,11 @@ module ActiveRecordExtended
|
|
89
89
|
union_values: Array,
|
90
90
|
union_operations: Array,
|
91
91
|
union_ordering_values: Array,
|
92
|
-
unionized_name: lambda { |klass| klass.arel_table.name }
|
92
|
+
unionized_name: lambda { |klass| klass.arel_table.name }
|
93
93
|
}.each_pair do |method_name, default|
|
94
94
|
define_method(method_name) do
|
95
95
|
return unionize_storage[method_name] if send("#{method_name}?")
|
96
|
+
|
96
97
|
(default.is_a?(Proc) ? default.call(@klass) : default.new)
|
97
98
|
end
|
98
99
|
|
@@ -107,11 +108,13 @@ module ActiveRecordExtended
|
|
107
108
|
|
108
109
|
def union(opts = :chain, *args)
|
109
110
|
return UnionChain.new(spawn) if opts == :chain
|
111
|
+
|
110
112
|
opts.nil? ? self : spawn.union!(opts, *args, chain_method: __callee__)
|
111
113
|
end
|
112
114
|
|
113
115
|
(UNIONIZE_METHODS + UNION_RELATION_METHODS).each do |union_method|
|
114
116
|
next if union_method == :union
|
117
|
+
|
115
118
|
alias_method union_method, :union
|
116
119
|
end
|
117
120
|
|
@@ -126,11 +129,13 @@ module ActiveRecordExtended
|
|
126
129
|
# Will construct *Just* the union SQL statement that was been built thus far
|
127
130
|
def to_union_sql
|
128
131
|
return unless union_values?
|
132
|
+
|
129
133
|
apply_union_ordering(build_union_nodes!(false)).to_sql
|
130
134
|
end
|
131
135
|
|
132
136
|
def to_nice_union_sql(color = true)
|
133
137
|
return to_union_sql unless defined?(::Niceql)
|
138
|
+
|
134
139
|
::Niceql::Prettifier.prettify_sql(to_union_sql, color)
|
135
140
|
end
|
136
141
|
|
@@ -172,7 +177,7 @@ module ActiveRecordExtended
|
|
172
177
|
|
173
178
|
def build_union_nodes!(raise_error = true)
|
174
179
|
unionize_error_or_warn!(raise_error)
|
175
|
-
union_values.each_with_index.
|
180
|
+
union_values.each_with_index.reduce(nil) do |union_node, (relation_node, index)|
|
176
181
|
next resolve_relation_node(relation_node) if union_node.nil?
|
177
182
|
|
178
183
|
operation = union_operations.fetch(index - 1, :union)
|
@@ -215,6 +220,7 @@ module ActiveRecordExtended
|
|
215
220
|
#
|
216
221
|
def apply_union_ordering(union_nodes)
|
217
222
|
return union_nodes unless union_ordering_values?
|
223
|
+
|
218
224
|
UnionChain.new(self).inline_order_by(union_nodes, union_ordering_values)
|
219
225
|
end
|
220
226
|
|
@@ -222,7 +228,7 @@ module ActiveRecordExtended
|
|
222
228
|
|
223
229
|
def unionize_error_or_warn!(raise_error = true)
|
224
230
|
if raise_error && union_values.size <= 1
|
225
|
-
raise ArgumentError
|
231
|
+
raise ArgumentError.new("You are required to provide 2 or more unions to join!")
|
226
232
|
elsif !raise_error && union_values.size <= 1
|
227
233
|
warn("Warning: You are required to provide 2 or more unions to join.")
|
228
234
|
end
|