active_record_extended 1.1.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.
Files changed (48) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +87 -15
  3. data/lib/active_record_extended.rb +2 -1
  4. data/lib/active_record_extended/active_record.rb +2 -9
  5. data/lib/active_record_extended/active_record/relation_patch.rb +21 -4
  6. data/lib/active_record_extended/arel.rb +2 -0
  7. data/lib/active_record_extended/arel/aggregate_function_name.rb +40 -0
  8. data/lib/active_record_extended/arel/nodes.rb +32 -41
  9. data/lib/active_record_extended/arel/predications.rb +4 -1
  10. data/lib/active_record_extended/arel/sql_literal.rb +16 -0
  11. data/lib/active_record_extended/arel/visitors/postgresql_decorator.rb +40 -1
  12. data/lib/active_record_extended/query_methods/any_of.rb +10 -8
  13. data/lib/active_record_extended/query_methods/either.rb +1 -1
  14. data/lib/active_record_extended/query_methods/inet.rb +7 -3
  15. data/lib/active_record_extended/query_methods/json.rb +156 -50
  16. data/lib/active_record_extended/query_methods/select.rb +118 -0
  17. data/lib/active_record_extended/query_methods/unionize.rb +14 -43
  18. data/lib/active_record_extended/query_methods/where_chain.rb +14 -6
  19. data/lib/active_record_extended/query_methods/window.rb +93 -0
  20. data/lib/active_record_extended/query_methods/with_cte.rb +102 -35
  21. data/lib/active_record_extended/utilities/order_by.rb +77 -0
  22. data/lib/active_record_extended/utilities/support.rb +178 -0
  23. data/lib/active_record_extended/version.rb +1 -1
  24. data/spec/query_methods/any_of_spec.rb +40 -40
  25. data/spec/query_methods/array_query_spec.rb +14 -14
  26. data/spec/query_methods/either_spec.rb +14 -14
  27. data/spec/query_methods/hash_query_spec.rb +11 -11
  28. data/spec/query_methods/inet_query_spec.rb +33 -31
  29. data/spec/query_methods/json_spec.rb +42 -27
  30. data/spec/query_methods/select_spec.rb +115 -0
  31. data/spec/query_methods/unionize_spec.rb +56 -56
  32. data/spec/query_methods/window_spec.rb +51 -0
  33. data/spec/query_methods/with_cte_spec.rb +22 -12
  34. data/spec/spec_helper.rb +1 -1
  35. data/spec/sql_inspections/any_of_sql_spec.rb +12 -12
  36. data/spec/sql_inspections/arel/aggregate_function_name_spec.rb +41 -0
  37. data/spec/sql_inspections/arel/array_spec.rb +7 -7
  38. data/spec/sql_inspections/arel/inet_spec.rb +7 -7
  39. data/spec/sql_inspections/contains_sql_queries_spec.rb +14 -14
  40. data/spec/sql_inspections/either_sql_spec.rb +11 -11
  41. data/spec/sql_inspections/json_sql_spec.rb +44 -8
  42. data/spec/sql_inspections/unionize_sql_spec.rb +27 -27
  43. data/spec/sql_inspections/window_sql_spec.rb +98 -0
  44. data/spec/sql_inspections/with_cte_sql_spec.rb +52 -23
  45. data/spec/support/models.rb +24 -4
  46. metadata +31 -20
  47. data/lib/active_record_extended/patch/5_0/predicate_builder_decorator.rb +0 -87
  48. data/lib/active_record_extended/utilities.rb +0 -141
@@ -3,112 +3,113 @@
3
3
  require "spec_helper"
4
4
 
5
5
  RSpec.describe "Active Record Union Methods" do
6
- let!(:person_one) { Person.create!(number: 8) }
7
- let!(:person_two) { Person.create!(number: 10) }
8
- let!(:person_three) { Person.create!(number: 1) }
9
- let!(:person_one_pl) { ProfileL.create!(person: person_one, likes: 100) }
10
- let!(:person_two_pl) { ProfileL.create!(person: person_two, likes: 200) }
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(:person_one_query) { Person.select(:id).where(id: person_one.id) }
14
- let(:person_two_query) { Person.select(:id, :tags).where(id: person_two.id) }
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
 
18
18
  it "should raise an error if the select statements do not align" do
19
19
  expect { misaligned_cmd.to_a }.to(
20
- raise_error(ActiveRecord::StatementInvalid, /each [[:alpha:]]+ query must have the same number of columns/),
20
+ raise_error(ActiveRecord::StatementInvalid, /each [[:alpha:]]+ query must have the same number of columns/)
21
21
  )
22
22
  end
23
23
 
24
24
  it "should raise an argument error if there are less then two union statements" do
25
25
  expect { lacking_union_cmd.to_a }.to(
26
- raise_error(ArgumentError, "You are required to provide 2 or more unions to join!"),
26
+ raise_error(ArgumentError, "You are required to provide 2 or more unions to join!")
27
27
  )
28
28
  end
29
29
  end
30
30
 
31
31
  describe ".union" do
32
32
  it_behaves_like "standard set of errors" do
33
- let!(:misaligned_cmd) { Person.union(person_one_query, person_two_query) }
34
- let!(:lacking_union_cmd) { Person.union(person_one_query) }
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 = Person.union(Person.where(id: person_one.id), Person.where(id: person_three.id))
39
- expect(query).to match_array([person_one, person_three])
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 = Person.union(Person.where(id: person_one.id), Person.joins(:profile_l).where.not(id: person_one.id))
44
- expect(query).to match_array([person_one, person_two])
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 = Person.pluck(:id)
49
- query = Person.union(Person.select(:id), Person.select(:id))
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) { Person.union.all(person_one_query, person_two_query) }
57
- let!(:lacking_union_cmd) { Person.union.all(person_one_query) }
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 = Person.pluck(:id) * 2
62
- query = Person.union.all(Person.select(:id), Person.select(:id))
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) { Person.union.except(person_one_query, person_two_query) }
70
- let!(:lacking_union_cmd) { Person.union.except(person_one_query) }
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 = Person.union.except(Person.select(:id), Person.select(:id).where(id: person_one.id))
75
- expect(query).to match_array([person_two, person_three])
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) { Person.union.intersect(person_one_query, person_two_query) }
82
- let!(:lacking_union_cmd) { Person.union.intersect(person_one_query) }
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!(person: person_three, likes: 120)
86
+ ProfileL.create!(user: user_three, likes: 120)
87
87
 
88
88
  query =
89
- Person.union.intersect(
90
- Person.select(:id, "profile_ls.likes").joins(:profile_l).where(profile_ls: { likes: 100 }),
91
- Person.select(:id, "profile_ls.likes").joins(:profile_l).where("profile_ls.likes < 150"),
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([person_one_pl.id]))
95
- expect(query.first.likes).to eq(person_one_pl.likes)
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
- Person.select("happy_people.id")
102
- .union(Person.where(id: person_one.id), Person.where(id: person_three.id))
103
- .union_as(:happy_people)
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 people" do
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 peoples id's" do
111
- expect(query.map(&:id)).to match_array([person_one.id, person_three.id])
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 = Person.union(Person.where(id: person_one.id), Person.where(id: person_three.id)).order_union(id: :desc)
124
- expect(query).to eq([person_three, person_one])
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
- Person.union.all(
130
- Person.where(id: person_one.id),
131
- Person.where(id: person_three.id),
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([person_three, person_one])
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 = Person.union.except(Person.order(id: :asc), Person.where(id: person_one.id)).order_union(id: :desc)
139
- expect(query).to eq([person_three, person_two])
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
- Person.union.intersect(
145
- Person.where("id < ?", person_three.id),
146
- Person.where("id >= ?", person_one.id),
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([person_two, person_one])
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
- person_a = Person.create!(number: 1)
156
- person_b = Person.create!(number: 10)
157
- initial_ordering = [person_b, person_a]
158
- query = Person.union(Person.where(id: person_a.id), Person.where(id: person_b.id))
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)
@@ -0,0 +1,51 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe "Active Record Window Function Query Methods" do
6
+ let!(:user_one) { User.create! }
7
+ let!(:user_two) { User.create! }
8
+
9
+ let!(:tag_one) { Tag.create!(user: user_one, tag_number: 1) }
10
+ let!(:tag_two) { Tag.create!(user: user_two, tag_number: 2) }
11
+
12
+ let!(:tag_three) { Tag.create!(user: user_one, tag_number: 3) }
13
+ let!(:tag_four) { Tag.create!(user: user_two, tag_number: 4) }
14
+
15
+ let(:tag_group1) { [tag_one, tag_three] }
16
+ let(:tag_group2) { [tag_two, tag_four] }
17
+
18
+ describe ".window_select" do
19
+ context "when using ROW_NUMBER() ordered in asc" do
20
+ let(:base_query) do
21
+ Tag.define_window(:w).partition_by(:user_id, order_by: :tag_number).select(:id)
22
+ end
23
+
24
+ it "should return tag_one with r_id 1 and tag_three with r_id 2" do
25
+ results = base_query.select_window(:row_number, over: :w, as: :r_id).group_by(&:id)
26
+ tag_group1.each.with_index { |tag, idx| expect(results[tag.id].first.r_id).to eq(idx + 1) }
27
+ end
28
+
29
+ it "should return tag_two with r_id 1 and tag_four with r_id 2" do
30
+ results = base_query.select_window(:row_number, over: :w, as: :r_id).group_by(&:id)
31
+ tag_group2.each.with_index { |tag, idx| expect(results[tag.id].first.r_id).to eq(idx + 1) }
32
+ end
33
+ end
34
+
35
+ context "when using ROW_NUMBER() ordered in desc" do
36
+ let(:base_query) do
37
+ Tag.define_window(:w).partition_by(:user_id, order_by: { tag_number: :desc }).select(:id)
38
+ end
39
+
40
+ it "should return tag_one with r_id 2 and tag_three with r_id 1" do
41
+ results = base_query.select_window(:row_number, over: :w, as: :r_id).group_by(&:id)
42
+ tag_group1.reverse_each.with_index { |tag, idx| expect(results[tag.id].first.r_id).to eq(idx + 1) }
43
+ end
44
+
45
+ it "should return tag_two with r_id 2 and tag_four with r_id 1" do
46
+ results = base_query.select_window(:row_number, over: :w, as: :r_id).group_by(&:id)
47
+ tag_group2.reverse_each.with_index { |tag, idx| expect(results[tag.id].first.r_id).to eq(idx + 1) }
48
+ end
49
+ end
50
+ end
51
+ end
@@ -3,25 +3,25 @@
3
3
  require "spec_helper"
4
4
 
5
5
  RSpec.describe "Active Record With CTE Query Methods" do
6
- let!(:person_one) { Person.create! }
7
- let!(:person_two) { Person.create! }
8
- let!(:profile_one) { ProfileL.create!(person_id: person_one.id, likes: 200) }
9
- let!(:profile_two) { ProfileL.create!(person_id: person_two.id, likes: 500) }
6
+ let!(:user_one) { User.create! }
7
+ let!(:user_two) { User.create! }
8
+ let!(:profile_one) { ProfileL.create!(user_id: user_one.id, likes: 200) }
9
+ let!(:profile_two) { ProfileL.create!(user_id: user_two.id, likes: 500) }
10
10
 
11
11
  describe ".with/1" do
12
12
  context "when using as a standalone query" do
13
13
  it "should only return a person with less than 300 likes" do
14
- query = Person.with(profile: ProfileL.where("likes < 300"))
15
- .joins("JOIN profile ON profile.id = people.id")
14
+ query = User.with(profile: ProfileL.where("likes < 300"))
15
+ .joins("JOIN profile ON profile.id = users.id")
16
16
 
17
- expect(query).to match_array([person_one])
17
+ expect(query).to match_array([user_one])
18
18
  end
19
19
 
20
20
  it "should return anyone with likes greater than or equal to 200" do
21
- query = Person.with(profile: ProfileL.where("likes >= 200"))
22
- .joins("JOIN profile ON profile.id = people.id")
21
+ query = User.with(profile: ProfileL.where("likes >= 200"))
22
+ .joins("JOIN profile ON profile.id = users.id")
23
23
 
24
- expect(query).to match_array([person_one, person_two])
24
+ expect(query).to match_array([user_one, user_two])
25
25
  end
26
26
  end
27
27
 
@@ -31,9 +31,19 @@ RSpec.describe "Active Record With CTE Query Methods" do
31
31
 
32
32
  it "will maintain the CTE table when merging into existing AR queries" do
33
33
  sub_query = ProfileL.with(version_controls: VersionControl.where.contains(source: { help: "me" }))
34
- query = Person.joins(profile_l: :version).merge(sub_query)
34
+ query = User.joins(profile_l: :version).merge(sub_query)
35
35
 
36
- expect(query).to match_array([person_one])
36
+ expect(query).to match_array([user_one])
37
+ end
38
+
39
+ it "should contain a unique list of ordered CTE keys when merging in multiple children" do
40
+ x = User.with(profile: ProfileL.where("likes < 300"))
41
+ y = User.with(profile: ProfileL.where("likes > 400"))
42
+ z = y.merge(x).joins("JOIN profile ON profile.id = users.id") # Y should reject X's CTE (FIFO)
43
+ query = User.with(my_profile: z).joins("JOIN my_profile ON my_profile.id = users.id")
44
+
45
+ expect(query.cte.with_keys).to eq([:profile, :my_profile])
46
+ expect(query).to match_array([user_two])
37
47
  end
38
48
  end
39
49
  end
@@ -13,7 +13,7 @@ end
13
13
  ActiveRecord::Base.establish_connection(ENV["DATABASE_URL"])
14
14
 
15
15
  Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require File.expand_path(f) }
16
- Dir["#{File.dirname(__FILE__)}/**/*examples.rb"].each { |f| require f }
16
+ Dir["#{File.dirname(__FILE__)}/**/*examples.rb"].sort.each { |f| require f }
17
17
 
18
18
  RSpec.configure do |config|
19
19
  # Enable flags like --only-failures and --next-failure
@@ -3,30 +3,30 @@
3
3
  require "spec_helper"
4
4
 
5
5
  RSpec.describe "Any / None of SQL Queries" do
6
- let(:equal_query) { '"people"."personal_id" = 1' }
7
- let(:or_query) { 'OR "people"."personal_id" = 2' }
8
- let(:equal_or) { equal_query + " " + or_query }
9
- let(:join_query) { /INNER JOIN \"tags\" ON \"tags\".\"person_id\" = \"people\".\"id/ }
6
+ let(:equal_query) { '"users"."personal_id" = 1' }
7
+ let(:or_query) { 'OR "users"."personal_id" = 2' }
8
+ let(:equal_or) { "#{equal_query} #{or_query}" }
9
+ let(:join_query) { /INNER JOIN "tags" ON "tags"."user_id" = "users"."id/ }
10
10
 
11
11
  describe "where.any_of/1" do
12
12
  it "should group different column arguments into nested or conditions" do
13
- query = Person.where.any_of({ personal_id: 1 }, { id: 2 }, { personal_id: 2 }).to_sql
13
+ query = User.where.any_of({ personal_id: 1 }, { id: 2 }, { personal_id: 2 }).to_sql
14
14
  expect(query).to match_regex(/WHERE \(\(.+ = 1 OR .+ = 2\) OR .+ = 2\)/)
15
15
  end
16
16
 
17
17
  it "Should assign where clause predicates for standard queries" do
18
- query = Person.where.any_of({ personal_id: 1 }, { personal_id: 2 }).to_sql
18
+ query = User.where.any_of({ personal_id: 1 }, { personal_id: 2 }).to_sql
19
19
  expect(query).to include(equal_or)
20
20
 
21
- personal_one = Person.where(personal_id: 1)
22
- personal_two = Person.where(personal_id: 2)
23
- query = Person.where.any_of(personal_one, personal_two).to_sql
21
+ personal_one = User.where(personal_id: 1)
22
+ personal_two = User.where(personal_id: 2)
23
+ query = User.where.any_of(personal_one, personal_two).to_sql
24
24
  expect(query).to include(equal_or)
25
25
  end
26
26
 
27
27
  it "Joining queries should be added to the select statement" do
28
- person_two_tag = Person.where(personal_id: 1).joins(:hm_tags)
29
- query = Person.where.any_of(person_two_tag).to_sql
28
+ user_two_tag = User.where(personal_id: 1).joins(:hm_tags)
29
+ query = User.where.any_of(user_two_tag).to_sql
30
30
  expect(query).to match_regex(join_query)
31
31
  expect(query).to include(equal_query)
32
32
  end
@@ -34,7 +34,7 @@ RSpec.describe "Any / None of SQL Queries" do
34
34
 
35
35
  describe "where.none_of/1" do
36
36
  it "Should surround the query in a WHERE NOT clause" do
37
- query = Person.where.none_of({ personal_id: 1 }, { id: 2 }, { personal_id: 2 }).to_sql
37
+ query = User.where.none_of({ personal_id: 1 }, { id: 2 }, { personal_id: 2 }).to_sql
38
38
  expect(query).to match_regex(/WHERE.+NOT \(\(.+ = 1 OR .+ = 2\) OR .+ = 2\)/)
39
39
  end
40
40
  end
@@ -0,0 +1,41 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "spec_helper"
4
+
5
+ RSpec.describe Arel::Nodes::AggregateFunctionName do
6
+ describe "Custom Aggregate function" do
7
+ it "constructs an aggregate function based on a given name" do
8
+ query = described_class.new("MY_CUSTOM_AGG", [Arel.sql("id == me")])
9
+ expect(query.to_sql).to eq("MY_CUSTOM_AGG(id == me)")
10
+ end
11
+
12
+ it "can append multiple expressions" do
13
+ query = described_class.new("MY_CUSTOM_AGG", [Arel.sql("id == me"), Arel.sql("id == you")])
14
+ expect(query.to_sql).to eq("MY_CUSTOM_AGG(id == me, id == you)")
15
+ end
16
+
17
+ it "can append a distinct clause inside the aggregate" do
18
+ query = described_class.new("MY_CUSTOM_AGG", [Arel.sql("id == me")], true)
19
+ expect(query.to_sql).to eq("MY_CUSTOM_AGG(DISTINCT id == me)")
20
+ end
21
+
22
+ it "can append an order by clause when providing a ordering expression" do
23
+ order_expr = Arel.sql("id").desc
24
+ query = described_class.new("MY_CUSTOM_AGG", [Arel.sql("id == me")], true).order_by([order_expr])
25
+ expect(query.to_sql).to eq("MY_CUSTOM_AGG(DISTINCT id == me ORDER BY id DESC)")
26
+ end
27
+
28
+ it "can append multiple ordering clauses" do
29
+ expr = Arel.sql("id").desc
30
+ other_expr = Arel.sql("name").asc
31
+ query = described_class.new("MY_CUSTOM_AGG", [Arel.sql("id == me")], true).order_by([expr, other_expr])
32
+ expect(query.to_sql).to eq("MY_CUSTOM_AGG(DISTINCT id == me ORDER BY id DESC, name ASC)")
33
+ end
34
+
35
+ it "can be aliased" do
36
+ alias_as = Arel.sql("new_name")
37
+ query = described_class.new("MY_CUSTOM_AGG", [Arel.sql("id == me")], true).as(alias_as)
38
+ expect(query.to_sql).to eq("MY_CUSTOM_AGG(DISTINCT id == me) AS new_name")
39
+ end
40
+ end
41
+ end
@@ -3,7 +3,7 @@
3
3
  require "spec_helper"
4
4
 
5
5
  RSpec.describe "Array Column Predicates" do
6
- let(:arel_table) { Person.arel_table }
6
+ let(:arel_table) { User.arel_table }
7
7
 
8
8
  describe "Array Overlap" do
9
9
  it "converts Arel overlap statement" do
@@ -17,7 +17,7 @@ RSpec.describe "Array Column Predicates" do
17
17
  end
18
18
 
19
19
  it "works with count (and other predicates)" do
20
- expect(Person.where(arel_table[:tag_ids].overlap([1, 2])).count).to eq 0
20
+ expect(User.where(arel_table[:tag_ids].overlap([1, 2])).count).to eq 0
21
21
  end
22
22
  end
23
23
 
@@ -33,31 +33,31 @@ RSpec.describe "Array Column Predicates" do
33
33
  end
34
34
 
35
35
  it "works with count (and other predicates)" do
36
- expect(Person.where(arel_table[:tag_ids].contains([1, 2])).count).to eq 0
36
+ expect(User.where(arel_table[:tag_ids].contains([1, 2])).count).to eq 0
37
37
  end
38
38
  end
39
39
 
40
40
  describe "Any Array Element" do
41
41
  it "creates any predicates that contain a string value" do
42
42
  query = arel_table.where(arel_table[:tags].any("tag")).to_sql
43
- expect(query).to match_regex(/'tag' = ANY\("people"\."tags"\)/)
43
+ expect(query).to match_regex(/'tag' = ANY\("users"\."tags"\)/)
44
44
  end
45
45
 
46
46
  it "creates any predicates that contain a integer value" do
47
47
  query = arel_table.where(arel_table[:tags].any(2)).to_sql
48
- expect(query).to match_regex(/2 = ANY\("people"\."tags"\)/)
48
+ expect(query).to match_regex(/2 = ANY\("users"\."tags"\)/)
49
49
  end
50
50
  end
51
51
 
52
52
  describe "All Array Elements" do
53
53
  it "create all predicates that contain a string value" do
54
54
  query = arel_table.where(arel_table[:tags].all("tag")).to_sql
55
- expect(query).to match_regex(/'tag' = ALL\("people"\."tags"\)/)
55
+ expect(query).to match_regex(/'tag' = ALL\("users"\."tags"\)/)
56
56
  end
57
57
 
58
58
  it "create all predicates that contain a interger value" do
59
59
  query = arel_table.where(arel_table[:tags].all(2)).to_sql
60
- expect(query).to match_regex(/2 = ALL\("people"\."tags"\)/)
60
+ expect(query).to match_regex(/2 = ALL\("users"\."tags"\)/)
61
61
  end
62
62
  end
63
63
  end