active_record_extended 1.1.0 → 1.2.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 +12 -18
- data/lib/active_record_extended.rb +2 -1
- data/lib/active_record_extended/active_record.rb +2 -0
- data/lib/active_record_extended/active_record/relation_patch.rb +1 -1
- data/lib/active_record_extended/arel.rb +1 -0
- data/lib/active_record_extended/arel/aggregate_function_name.rb +40 -0
- data/lib/active_record_extended/arel/nodes.rb +31 -41
- data/lib/active_record_extended/arel/predications.rb +4 -1
- data/lib/active_record_extended/arel/visitors/postgresql_decorator.rb +40 -1
- data/lib/active_record_extended/patch/5_0/predicate_builder_decorator.rb +4 -4
- data/lib/active_record_extended/patch/5_0/regex_match.rb +10 -0
- data/lib/active_record_extended/query_methods/any_of.rb +5 -4
- data/lib/active_record_extended/query_methods/inet.rb +1 -1
- data/lib/active_record_extended/query_methods/json.rb +152 -43
- data/lib/active_record_extended/query_methods/select.rb +117 -0
- data/lib/active_record_extended/query_methods/unionize.rb +4 -39
- data/lib/active_record_extended/query_methods/with_cte.rb +3 -3
- data/lib/active_record_extended/utilities/order_by.rb +96 -0
- data/lib/active_record_extended/utilities/support.rb +175 -0
- data/lib/active_record_extended/version.rb +1 -1
- data/spec/query_methods/any_of_spec.rb +40 -40
- data/spec/query_methods/array_query_spec.rb +14 -14
- data/spec/query_methods/either_spec.rb +14 -14
- data/spec/query_methods/hash_query_spec.rb +11 -11
- data/spec/query_methods/inet_query_spec.rb +33 -31
- data/spec/query_methods/json_spec.rb +40 -25
- data/spec/query_methods/select_spec.rb +115 -0
- data/spec/query_methods/unionize_spec.rb +54 -54
- data/spec/query_methods/with_cte_spec.rb +12 -12
- data/spec/sql_inspections/any_of_sql_spec.rb +11 -11
- data/spec/sql_inspections/arel/aggregate_function_name_spec.rb +41 -0
- data/spec/sql_inspections/arel/array_spec.rb +7 -7
- data/spec/sql_inspections/arel/inet_spec.rb +7 -7
- data/spec/sql_inspections/contains_sql_queries_spec.rb +14 -14
- data/spec/sql_inspections/either_sql_spec.rb +11 -11
- data/spec/sql_inspections/json_sql_spec.rb +38 -8
- data/spec/sql_inspections/unionize_sql_spec.rb +27 -27
- data/spec/sql_inspections/with_cte_sql_spec.rb +22 -22
- data/spec/support/models.rb +18 -4
- metadata +11 -3
- data/lib/active_record_extended/utilities.rb +0 -141
@@ -1,29 +1,44 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
RSpec.describe "Active Record JSON methods" do
|
4
|
-
let!(:
|
5
|
-
let!(:
|
4
|
+
let!(:user_one) { User.create! }
|
5
|
+
let!(:user_two) { User.create! }
|
6
6
|
|
7
7
|
describe ".select_row_to_json" do
|
8
|
-
let!(:tag_one) { Tag.create!(
|
9
|
-
let!(:tag_two) { Tag.create!(
|
10
|
-
let(:sub_query) { Tag.select(:tag_number).where("tags.
|
8
|
+
let!(:tag_one) { Tag.create!(user: user_one, tag_number: 2) }
|
9
|
+
let!(:tag_two) { Tag.create!(user: user_two, tag_number: 5) }
|
10
|
+
let(:sub_query) { Tag.select(:tag_number).where("tags.user_id = users.id") }
|
11
11
|
|
12
12
|
it "should nest a json object in the query results" do
|
13
|
-
query =
|
13
|
+
query = User.select(:id).select_row_to_json(sub_query, as: :results).where(id: user_one.id)
|
14
14
|
expect(query.size).to eq(1)
|
15
15
|
expect(query.take.results).to be_a(Hash).and(match("tag_number" => 2))
|
16
16
|
end
|
17
17
|
|
18
18
|
# ugh wording here sucks, brain is fried.
|
19
19
|
it "accepts a block for appending additional scopes to the middle-top level" do
|
20
|
-
query =
|
20
|
+
query = User.select(:id).select_row_to_json(sub_query, key: :tag_row, as: :results) do |scope|
|
21
21
|
scope.where("tag_row.tag_number = 5")
|
22
22
|
end
|
23
23
|
|
24
24
|
expect(query.size).to eq(2)
|
25
25
|
query.each do |result|
|
26
|
-
if result.id ==
|
26
|
+
if result.id == user_one.id
|
27
|
+
expect(result.results).to be_blank
|
28
|
+
else
|
29
|
+
expect(result.results).to be_present.and(match("tag_number" => 5))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
it "accepts a scope-block without arguments" do
|
35
|
+
query = User.select(:id).select_row_to_json(sub_query, key: :tag_row, as: :results) do
|
36
|
+
where("tag_row.tag_number = 5")
|
37
|
+
end
|
38
|
+
|
39
|
+
expect(query.size).to eq(2)
|
40
|
+
query.each do |result|
|
41
|
+
if result.id == user_one.id
|
27
42
|
expect(result.results).to be_blank
|
28
43
|
else
|
29
44
|
expect(result.results).to be_present.and(match("tag_number" => 5))
|
@@ -32,56 +47,56 @@ RSpec.describe "Active Record JSON methods" do
|
|
32
47
|
end
|
33
48
|
|
34
49
|
it "allows for casting results in an aggregate-able Array function" do
|
35
|
-
query =
|
50
|
+
query = User.select(:id).select_row_to_json(sub_query, key: :tag_row, as: :results, cast_as_array: true)
|
36
51
|
expect(query.take.results).to be_a(Array).and(be_present)
|
37
52
|
expect(query.take.results.first).to be_a(Hash)
|
38
53
|
end
|
39
54
|
|
40
55
|
it "raises an error if a from clause key is missing" do
|
41
56
|
expect do
|
42
|
-
|
57
|
+
User.select(:id).select_row_to_json(key: :tag_row, as: :results)
|
43
58
|
end.to raise_error(ArgumentError)
|
44
59
|
end
|
45
60
|
end
|
46
61
|
|
47
62
|
describe ".json_build_object" do
|
48
63
|
let(:sub_query) do
|
49
|
-
|
64
|
+
User.select_row_to_json(from: User.select(:id), cast_as_array: true, as: :ids).where(id: user_one.id)
|
50
65
|
end
|
51
66
|
|
52
67
|
it "defaults the column alias if one is not provided" do
|
53
|
-
query =
|
68
|
+
query = User.json_build_object(:personal, sub_query)
|
54
69
|
expect(query.size).to eq(1)
|
55
70
|
expect(query.take.results).to match(
|
56
|
-
"personal" => match("ids" => match_array([{ "id" =>
|
71
|
+
"personal" => match("ids" => match_array([{ "id" => user_one.id }, { "id" => user_two.id }])),
|
57
72
|
)
|
58
73
|
end
|
59
74
|
|
60
75
|
it "allows for re-aliasing the default 'results' column" do
|
61
|
-
query =
|
76
|
+
query = User.json_build_object(:personal, sub_query, as: :cool_dudes)
|
62
77
|
expect(query.take).to respond_to(:cool_dudes)
|
63
78
|
end
|
64
79
|
end
|
65
80
|
|
66
81
|
describe ".jsonb_build_object" do
|
67
|
-
let(:sub_query) {
|
82
|
+
let(:sub_query) { User.select(:id, :number).where(id: user_one.id) }
|
68
83
|
|
69
84
|
it "defaults the column alias if one is not provided" do
|
70
|
-
query =
|
85
|
+
query = User.jsonb_build_object(:personal, sub_query)
|
71
86
|
expect(query.size).to eq(1)
|
72
87
|
expect(query.take.results).to be_a(Hash).and(be_present)
|
73
|
-
expect(query.take.results).to match("personal" => match("id" =>
|
88
|
+
expect(query.take.results).to match("personal" => match("id" => user_one.id, "number" => user_one.number))
|
74
89
|
end
|
75
90
|
|
76
91
|
it "allows for re-aliasing the default 'results' column" do
|
77
|
-
query =
|
92
|
+
query = User.jsonb_build_object(:personal, sub_query, as: :cool_dudes)
|
78
93
|
expect(query.take).to respond_to(:cool_dudes)
|
79
94
|
end
|
80
95
|
|
81
96
|
it "allows for custom value statement" do
|
82
|
-
query =
|
97
|
+
query = User.jsonb_build_object(
|
83
98
|
:personal,
|
84
|
-
sub_query.where.not(id:
|
99
|
+
sub_query.where.not(id: user_one),
|
85
100
|
value: "COALESCE(array_agg(\"personal\"), '{}')",
|
86
101
|
as: :cool_dudes,
|
87
102
|
)
|
@@ -91,9 +106,9 @@ RSpec.describe "Active Record JSON methods" do
|
|
91
106
|
|
92
107
|
it "will raise a warning if the value doesn't include a double quoted input" do
|
93
108
|
expect do
|
94
|
-
|
109
|
+
User.jsonb_build_object(
|
95
110
|
:personal,
|
96
|
-
sub_query.where.not(id:
|
111
|
+
sub_query.where.not(id: user_one),
|
97
112
|
value: "COALESCE(array_agg(personal), '{}')",
|
98
113
|
as: :cool_dudes,
|
99
114
|
)
|
@@ -109,19 +124,19 @@ RSpec.describe "Active Record JSON methods" do
|
|
109
124
|
let(:method) { raise "You are expected to over ride this!" }
|
110
125
|
|
111
126
|
it "will accept a hash arguments that will return itself" do
|
112
|
-
query =
|
127
|
+
query = User.send(method.to_sym, original_hash)
|
113
128
|
expect(query.take.results).to be_a(Hash).and(be_present)
|
114
129
|
expect(query.take.results).to match(original_hash.stringify_keys)
|
115
130
|
end
|
116
131
|
|
117
132
|
it "will accept a standard array of key values" do
|
118
|
-
query =
|
133
|
+
query = User.send(method.to_sym, hash_as_array_objs)
|
119
134
|
expect(query.take.results).to be_a(Hash).and(be_present)
|
120
135
|
expect(query.take.results).to match(original_hash.stringify_keys)
|
121
136
|
end
|
122
137
|
|
123
138
|
it "will accept a splatted array of key-values" do
|
124
|
-
query =
|
139
|
+
query = User.send(method.to_sym, *hash_as_array_objs)
|
125
140
|
expect(query.take.results).to be_a(Hash).and(be_present)
|
126
141
|
expect(query.take.results).to match(original_hash.stringify_keys)
|
127
142
|
end
|
@@ -0,0 +1,115 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "spec_helper"
|
4
|
+
|
5
|
+
RSpec.describe "Active Record Select Methods" do
|
6
|
+
let(:numbers) { (1..10).to_a }
|
7
|
+
|
8
|
+
describe ".foster_select" do
|
9
|
+
context "with an aggregate function" do
|
10
|
+
context "agg_array" do
|
11
|
+
let(:number_set) { numbers.sample(6).to_enum }
|
12
|
+
let!(:users) { Array.new(6) { User.create!(number: number_set.next, ip: "127.0.0.1") } }
|
13
|
+
let!(:tags) { users.flat_map { |u| Array.new(2) { Tag.create!(user: u, tag_number: numbers.sample) } } }
|
14
|
+
|
15
|
+
it "can accept a subquery" do
|
16
|
+
subquery = Tag.select("count(*)").joins("JOIN users u ON tags.user_id = u.id").where("u.ip = users.ip")
|
17
|
+
query =
|
18
|
+
User.foster_select(tag_count: [subquery, cast_with: :array_agg, distinct: true])
|
19
|
+
.joins(:hm_tags)
|
20
|
+
.group(:ip)
|
21
|
+
.take
|
22
|
+
|
23
|
+
expect(query.tag_count).to eq([tags.size])
|
24
|
+
end
|
25
|
+
|
26
|
+
it "can be ordered" do
|
27
|
+
query = User.foster_select(
|
28
|
+
asc_ordered_numbers: [:number, cast_with: :array_agg, order_by: { number: :asc }],
|
29
|
+
desc_ordered_numbers: [:number, cast_with: :array_agg, order_by: { number: :desc }],
|
30
|
+
).take
|
31
|
+
|
32
|
+
expect(query.asc_ordered_numbers).to eq(number_set.to_a.sort)
|
33
|
+
expect(query.desc_ordered_numbers).to eq(number_set.to_a.sort.reverse)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "works with joined relations" do
|
37
|
+
query =
|
38
|
+
User.foster_select(tag_numbers: { tags: :tag_number, cast_with: :array_agg })
|
39
|
+
.joins(:hm_tags)
|
40
|
+
.take
|
41
|
+
expect(query.tag_numbers).to match_array(Tag.pluck(:tag_number))
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "bool_[and|or]" do
|
46
|
+
let!(:users) do
|
47
|
+
enum_numbers = numbers.to_enum
|
48
|
+
Array.new(6) { User.create!(number: enum_numbers.next, ip: "127.0.0.1") }
|
49
|
+
end
|
50
|
+
|
51
|
+
it "will return a boolean expression" do
|
52
|
+
query = User.foster_select(
|
53
|
+
truthly_expr: ["users.number > 0", cast_with: :bool_and],
|
54
|
+
falsey_expr: ["users.number > 200", cast_with: :bool_and],
|
55
|
+
other_true_expr: ["users.number > 4", cast_with: :bool_or],
|
56
|
+
other_false_expr: ["users.number > 6", cast_with: :bool_or],
|
57
|
+
).take
|
58
|
+
|
59
|
+
expect(query.truthly_expr).to be_truthy
|
60
|
+
expect(query.falsey_expr).to be_falsey
|
61
|
+
expect(query.other_true_expr).to be_truthy
|
62
|
+
expect(query.other_false_expr).to be_falsey
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
context "with math functions: sum|max|min|avg" do
|
67
|
+
before { 2.times.flat_map { |i| Array.new(2) { |j| User.create!(number: (i + 1) * j + 3) } } }
|
68
|
+
|
69
|
+
it "max" do
|
70
|
+
query = User.foster_select(max_num: [:number, cast_with: :max]).take
|
71
|
+
expect(query.max_num).to eq(5)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "min" do
|
75
|
+
query = User.foster_select(max_num: [:number, cast_with: :min]).take
|
76
|
+
expect(query.max_num).to eq(3)
|
77
|
+
end
|
78
|
+
|
79
|
+
it "sum" do
|
80
|
+
query = User.foster_select(
|
81
|
+
num_sum: [:number, cast_with: :sum],
|
82
|
+
distinct_sum: [:number, cast_with: :sum, distinct: true],
|
83
|
+
).take
|
84
|
+
|
85
|
+
expect(query.num_sum).to eq(15)
|
86
|
+
expect(query.distinct_sum).to eq(12)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "avg" do
|
90
|
+
query = User.foster_select(
|
91
|
+
num_avg: [:number, cast_with: :avg],
|
92
|
+
distinct_avg: [:number, cast_with: :avg, distinct: true],
|
93
|
+
).take
|
94
|
+
|
95
|
+
expect(query.num_avg).to eq(3.75)
|
96
|
+
expect(query.distinct_avg).to eq(4.0)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
context "with standard select items" do
|
102
|
+
let!(:user) { User.create!(name: "Test") }
|
103
|
+
|
104
|
+
it "works with no alias" do
|
105
|
+
query = User.foster_select(:name).take
|
106
|
+
expect(query.name).to eq(user.name)
|
107
|
+
end
|
108
|
+
|
109
|
+
it "works with alias" do
|
110
|
+
query = User.foster_select(my_name: :name).take
|
111
|
+
expect(query.my_name).to eq(user.name)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
@@ -3,15 +3,15 @@
|
|
3
3
|
require "spec_helper"
|
4
4
|
|
5
5
|
RSpec.describe "Active Record Union Methods" do
|
6
|
-
let!(:
|
7
|
-
let!(:
|
8
|
-
let!(:
|
9
|
-
let!(:
|
10
|
-
let!(:
|
6
|
+
let!(:user_one) { User.create!(number: 8) }
|
7
|
+
let!(:user_two) { User.create!(number: 10) }
|
8
|
+
let!(:user_three) { User.create!(number: 1) }
|
9
|
+
let!(:user_one_pl) { ProfileL.create!(user: user_one, likes: 100) }
|
10
|
+
let!(:user_two_pl) { ProfileL.create!(user: user_two, likes: 200) }
|
11
11
|
|
12
12
|
shared_examples_for "standard set of errors" do
|
13
|
-
let(:
|
14
|
-
let(:
|
13
|
+
let(:user_one_query) { User.select(:id).where(id: user_one.id) }
|
14
|
+
let(:user_two_query) { User.select(:id, :tags).where(id: user_two.id) }
|
15
15
|
let(:misaligned_cmd) { raise("required to override this 'let' statement") }
|
16
16
|
let(:lacking_union_cmd) { raise("required to override this 'let' statement") }
|
17
17
|
|
@@ -30,85 +30,86 @@ RSpec.describe "Active Record Union Methods" do
|
|
30
30
|
|
31
31
|
describe ".union" do
|
32
32
|
it_behaves_like "standard set of errors" do
|
33
|
-
let!(:misaligned_cmd) {
|
34
|
-
let!(:lacking_union_cmd) {
|
33
|
+
let!(:misaligned_cmd) { User.union(user_one_query, user_two_query) }
|
34
|
+
let!(:lacking_union_cmd) { User.union(user_one_query) }
|
35
35
|
end
|
36
36
|
|
37
37
|
it "should return two users that match the where conditions" do
|
38
|
-
query =
|
39
|
-
expect(query).to match_array([
|
38
|
+
query = User.union(User.where(id: user_one.id), User.where(id: user_three.id))
|
39
|
+
expect(query).to match_array([user_one, user_three])
|
40
40
|
end
|
41
41
|
|
42
42
|
it "should allow joins on union statements" do
|
43
|
-
query =
|
44
|
-
expect(query).to match_array([
|
43
|
+
query = User.union(User.where(id: user_one.id), User.joins(:profile_l).where.not(id: user_one.id))
|
44
|
+
expect(query).to match_array([user_one, user_two])
|
45
45
|
end
|
46
46
|
|
47
47
|
it "should eliminate duplicate results" do
|
48
|
-
expected_ids =
|
49
|
-
query =
|
48
|
+
expected_ids = User.pluck(:id)
|
49
|
+
query = User.union(User.select(:id), User.select(:id))
|
50
50
|
expect(query.pluck(:id)).to have_attributes(size: expected_ids.size).and(match_array(expected_ids))
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
54
|
describe ".union.all" do
|
55
55
|
it_behaves_like "standard set of errors" do
|
56
|
-
let!(:misaligned_cmd) {
|
57
|
-
let!(:lacking_union_cmd) {
|
56
|
+
let!(:misaligned_cmd) { User.union.all(user_one_query, user_two_query) }
|
57
|
+
let!(:lacking_union_cmd) { User.union.all(user_one_query) }
|
58
58
|
end
|
59
59
|
|
60
60
|
it "should keep duplicate results from each union statement" do
|
61
|
-
expected_ids =
|
62
|
-
query =
|
61
|
+
expected_ids = User.pluck(:id) * 2
|
62
|
+
query = User.union.all(User.select(:id), User.select(:id))
|
63
63
|
expect(query.pluck(:id)).to have_attributes(size: expected_ids.size).and(match_array(expected_ids))
|
64
64
|
end
|
65
65
|
end
|
66
66
|
|
67
67
|
describe ".union.except" do
|
68
68
|
it_behaves_like "standard set of errors" do
|
69
|
-
let!(:misaligned_cmd) {
|
70
|
-
let!(:lacking_union_cmd) {
|
69
|
+
let!(:misaligned_cmd) { User.union.except(user_one_query, user_two_query) }
|
70
|
+
let!(:lacking_union_cmd) { User.union.except(user_one_query) }
|
71
71
|
end
|
72
72
|
|
73
73
|
it "should eliminate records that match a given except statement" do
|
74
|
-
query =
|
75
|
-
expect(query).to match_array([
|
74
|
+
query = User.union.except(User.select(:id), User.select(:id).where(id: user_one.id))
|
75
|
+
expect(query).to match_array([user_two, user_three])
|
76
76
|
end
|
77
77
|
end
|
78
78
|
|
79
79
|
describe "union.intersect" do
|
80
80
|
it_behaves_like "standard set of errors" do
|
81
|
-
let!(:misaligned_cmd) {
|
82
|
-
let!(:lacking_union_cmd) {
|
81
|
+
let!(:misaligned_cmd) { User.union.intersect(user_one_query, user_two_query) }
|
82
|
+
let!(:lacking_union_cmd) { User.union.intersect(user_one_query) }
|
83
83
|
end
|
84
84
|
|
85
85
|
it "should find records with similar attributes" do
|
86
|
-
ProfileL.create!(
|
86
|
+
ProfileL.create!(user: user_three, likes: 120)
|
87
87
|
|
88
88
|
query =
|
89
|
-
|
90
|
-
|
91
|
-
|
89
|
+
User.union.intersect(
|
90
|
+
User.select(:id, "profile_ls.likes").joins(:profile_l).where(profile_ls: { likes: 100 }),
|
91
|
+
User.select(:id, "profile_ls.likes").joins(:profile_l).where("profile_ls.likes < 150"),
|
92
92
|
)
|
93
93
|
|
94
|
-
expect(query.pluck(:id)).to have_attributes(size: 1).and(eq([
|
95
|
-
expect(query.first.likes).to eq(
|
94
|
+
expect(query.pluck(:id)).to have_attributes(size: 1).and(eq([user_one_pl.id]))
|
95
|
+
expect(query.first.likes).to eq(user_one_pl.likes)
|
96
96
|
end
|
97
97
|
end
|
98
98
|
|
99
99
|
describe "union.as" do
|
100
100
|
let(:query) do
|
101
|
-
|
102
|
-
|
103
|
-
|
101
|
+
User
|
102
|
+
.select("happy_users.id")
|
103
|
+
.union(User.where(id: user_one.id), User.where(id: user_three.id))
|
104
|
+
.union_as(:happy_users)
|
104
105
|
end
|
105
106
|
|
106
|
-
it "should return two
|
107
|
+
it "should return two users" do
|
107
108
|
expect(query.size).to eq(2)
|
108
109
|
end
|
109
110
|
|
110
|
-
it "should return two
|
111
|
-
expect(query.map(&:id)).to match_array([
|
111
|
+
it "should return two userss id's" do
|
112
|
+
expect(query.map(&:id)).to match_array([user_one.id, user_three.id])
|
112
113
|
end
|
113
114
|
|
114
115
|
it "should alias the tables being union'd but still allow for accessing table methods" do
|
@@ -120,43 +121,42 @@ RSpec.describe "Active Record Union Methods" do
|
|
120
121
|
|
121
122
|
describe "union.order_union" do
|
122
123
|
it "should order the .union commands" do
|
123
|
-
query =
|
124
|
-
expect(query).to eq([
|
124
|
+
query = User.union(User.where(id: user_one.id), User.where(id: user_three.id)).order_union(id: :desc)
|
125
|
+
expect(query).to eq([user_three, user_one])
|
125
126
|
end
|
126
127
|
|
127
128
|
it "should order the .union.all commands" do
|
128
129
|
query =
|
129
|
-
|
130
|
-
|
131
|
-
|
130
|
+
User.union.all(
|
131
|
+
User.where(id: user_one.id),
|
132
|
+
User.where(id: user_three.id),
|
132
133
|
).order_union(id: :desc)
|
133
134
|
|
134
|
-
expect(query).to eq([
|
135
|
+
expect(query).to eq([user_three, user_one])
|
135
136
|
end
|
136
137
|
|
137
138
|
it "should order the union.except commands" do
|
138
|
-
query =
|
139
|
-
expect(query).to eq([
|
139
|
+
query = User.union.except(User.order(id: :asc), User.where(id: user_one.id)).order_union(id: :desc)
|
140
|
+
expect(query).to eq([user_three, user_two])
|
140
141
|
end
|
141
142
|
|
142
143
|
it "should order the .union.intersect commands" do
|
143
144
|
query =
|
144
|
-
|
145
|
-
|
146
|
-
|
145
|
+
User.union.intersect(
|
146
|
+
User.where("id < ?", user_three.id),
|
147
|
+
User.where("id >= ?", user_one.id),
|
147
148
|
).order_union(id: :desc)
|
148
149
|
|
149
|
-
expect(query).to eq([
|
150
|
+
expect(query).to eq([user_two, user_one])
|
150
151
|
end
|
151
152
|
end
|
152
153
|
|
153
154
|
describe "union.reorder_union" do
|
154
155
|
it "should replace the ordering with the new parameters" do
|
155
|
-
|
156
|
-
|
157
|
-
initial_ordering = [
|
158
|
-
query =
|
159
|
-
.order_union(id: :desc)
|
156
|
+
user_a = User.create!(number: 1)
|
157
|
+
user_b = User.create!(number: 10)
|
158
|
+
initial_ordering = [user_b, user_a]
|
159
|
+
query = User.union(User.where(id: user_a.id), User.where(id: user_b.id)).order_union(id: :desc)
|
160
160
|
|
161
161
|
expect(query).to eq(initial_ordering)
|
162
162
|
expect(query.reorder_union(number: :asc)).to eq(initial_ordering.reverse)
|