active_record_extended 1.1.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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