arel-helpers 2.2.0 → 2.12.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,64 +1,137 @@
1
- # encoding: UTF-8
2
-
3
1
  require 'spec_helper'
4
2
 
5
3
  describe ArelHelpers do
6
- describe "#join_association" do
7
- it "should work for a directly associated model" do
8
- Post.joins(ArelHelpers.join_association(Post, :comments)).to_sql.should ==
9
- 'SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"'
4
+ describe '#join_association' do
5
+ it 'should work for a directly associated model' do
6
+ expect(Post.joins(ArelHelpers.join_association(Post, :comments)).to_sql).to(
7
+ eq('SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"')
8
+ )
10
9
  end
11
10
 
12
- it "should work with an outer join" do
13
- Post.joins(ArelHelpers.join_association(Post, :comments, Arel::Nodes::OuterJoin)).to_sql.should ==
14
- 'SELECT "posts".* FROM "posts" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id"'
11
+ it 'should work with an outer join' do
12
+ expect(Post.joins(ArelHelpers.join_association(Post, :comments, Arel::Nodes::OuterJoin)).to_sql).to(
13
+ eq('SELECT "posts".* FROM "posts" LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id"')
14
+ )
15
15
  end
16
16
 
17
- it "should allow adding additional join conditions" do
18
- Post.joins(ArelHelpers.join_association(Post, :comments) do |assoc_name, join_conditions|
17
+ it 'should allow adding additional join conditions' do
18
+ sql = Post.joins(ArelHelpers.join_association(Post, :comments) do |_assoc_name, join_conditions|
19
19
  join_conditions.and(Comment[:id].eq(10))
20
- end).to_sql.should ==
21
- 'SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" AND "comments"."id" = 10'
20
+ end).to_sql
21
+
22
+ expect(sql).to eq <<-SQL.squish
23
+ SELECT "posts".* FROM "posts"
24
+ INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" AND "comments"."id" = 10
25
+ SQL
26
+ end
27
+
28
+ it 'should work for two models, one directly associated and the other indirectly' do
29
+ sql = Post
30
+ .joins(ArelHelpers.join_association(Post, :comments))
31
+ .joins(ArelHelpers.join_association(Comment, :author))
32
+ .to_sql
33
+
34
+ expect(sql).to eq <<-SQL.squish
35
+ SELECT "posts".* FROM "posts"
36
+ INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"
37
+ INNER JOIN "authors" ON "authors"."id" = "comments"."author_id"
38
+ SQL
39
+ end
40
+
41
+ it 'should work for a nested hash of association names' do
42
+ sql = Post
43
+ .joins(ArelHelpers.join_association(Post, { comments: :author }))
44
+ .to_sql
45
+
46
+ expect(sql).to eq <<-SQL.squish
47
+ SELECT "posts".* FROM "posts"
48
+ INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"
49
+ INNER JOIN "authors" ON "authors"."id" = "comments"."author_id"
50
+ SQL
22
51
  end
23
52
 
24
- it "should work for two models, one directly associated and the other indirectly" do
25
- Post
26
- .joins(ArelHelpers.join_association(Post, :comments))
27
- .joins(ArelHelpers.join_association(Comment, :author))
28
- .to_sql.should ==
29
- 'SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" INNER JOIN "authors" ON "authors"."id" = "comments"."author_id"'
53
+ it 'should work with outer joins when given a nested hash of association names' do
54
+ sql = Post.joins(ArelHelpers.join_association(Post, { comments: :author }, Arel::Nodes::OuterJoin)).to_sql
55
+
56
+ expect(sql).to eq <<-SQL.squish
57
+ SELECT "posts".* FROM "posts"
58
+ LEFT OUTER JOIN "comments" ON "comments"."post_id" = "posts"."id"
59
+ LEFT OUTER JOIN "authors" ON "authors"."id" = "comments"."author_id"
60
+ SQL
30
61
  end
31
62
 
32
- it "should be able to handle multiple associations" do
33
- Post.joins(ArelHelpers.join_association(Post, [:comments, :favorites])).to_sql.should ==
34
- 'SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" INNER JOIN "favorites" ON "favorites"."post_id" = "posts"."id"'
63
+ it 'should be able to handle multiple associations' do
64
+ expect(Post.joins(ArelHelpers.join_association(Post, %i[comments favorites])).to_sql).to(
65
+ eq <<-SQL.squish
66
+ SELECT "posts".* FROM "posts"
67
+ INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"
68
+ INNER JOIN "favorites" ON "favorites"."post_id" = "posts"."id"
69
+ SQL
70
+ )
35
71
  end
36
72
 
37
- it "should yield once for each association" do
38
- Post.joins(ArelHelpers.join_association(Post, [:comments, :favorites]) do |assoc_name, join_conditions|
73
+ it 'should yield once for each association' do
74
+ sql = Post.joins(ArelHelpers.join_association(Post, %i[comments favorites]) do |assoc_name, join_conditions|
39
75
  case assoc_name
40
- when :favorites
41
- join_conditions.or(Favorite[:amount].eq("lots"))
42
- when :comments
43
- join_conditions.and(Comment[:text].eq("Awesome post!"))
76
+ when :favorites
77
+ join_conditions.or(Favorite[:amount].eq('lots'))
78
+ when :comments
79
+ join_conditions.and(Comment[:text].eq('Awesome post!'))
44
80
  end
45
- end).to_sql.should ==
46
- 'SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" AND "comments"."text" = \'Awesome post!\' INNER JOIN "favorites" (ON "favorites"."post_id" = "posts"."id" OR "favorites"."amount" = \'lots\')'
81
+ end).to_sql
82
+
83
+ expect(sql).to eq <<-SQL.squish
84
+ SELECT "posts".* FROM "posts"
85
+ INNER JOIN "comments" ON "comments"."post_id" = "posts"."id" AND "comments"."text" = 'Awesome post!'
86
+ INNER JOIN "favorites" (ON "favorites"."post_id" = "posts"."id" OR "favorites"."amount" = 'lots')
87
+ SQL
47
88
  end
48
89
 
49
90
  it 'should be able to handle has_and_belongs_to_many associations' do
50
- CollabPost.joins(ArelHelpers.join_association(CollabPost, :authors)).to_sql.should ==
51
- 'SELECT "collab_posts".* FROM "collab_posts" INNER JOIN "authors_collab_posts" ON "authors_collab_posts"."collab_post_id" = "collab_posts"."id" INNER JOIN "authors" ON "authors"."id" = "authors_collab_posts"."author_id"'
91
+ sql = CollabPost.joins(ArelHelpers.join_association(CollabPost, :authors)).to_sql
92
+
93
+ expect(sql).to eq <<-SQL.squish
94
+ SELECT "collab_posts".* FROM "collab_posts"
95
+ INNER JOIN "authors_collab_posts" ON "authors_collab_posts"."collab_post_id" = "collab_posts"."id"
96
+ INNER JOIN "authors" ON "authors"."id" = "authors_collab_posts"."author_id"
97
+ SQL
98
+ end
99
+
100
+ it 'allows adding a custom alias to the joined table' do
101
+ Comment.aliased_as(:foo) do |foo|
102
+ sql = Post.joins(
103
+ ArelHelpers.join_association(Post, :comments, Arel::Nodes::InnerJoin, aliases: [foo])
104
+ ).to_sql
105
+
106
+ expect(sql).to eq 'SELECT "posts".* FROM "posts" INNER JOIN "comments" "foo" ON "foo"."post_id" = "posts"."id"'
107
+ end
108
+ end
109
+
110
+ it 'allows aliasing multiple associations' do
111
+ Comment.aliased_as(:foo) do |foo|
112
+ Favorite.aliased_as(:bar) do |bar|
113
+ sql = Post.joins(
114
+ ArelHelpers.join_association(Post, %i[comments favorites], Arel::Nodes::InnerJoin, aliases: [foo, bar])
115
+ ).to_sql
116
+
117
+ expect(sql).to eq <<-SQL.squish
118
+ SELECT "posts".* FROM "posts"
119
+ INNER JOIN "comments" "foo" ON "foo"."post_id" = "posts"."id"
120
+ INNER JOIN "favorites" "bar" ON "bar"."post_id" = "posts"."id"
121
+ SQL
122
+ end
123
+ end
52
124
  end
53
125
 
54
126
  it 'handles polymorphic through associations' do
55
- relation = Location.joins(
56
- ArelHelpers.join_association(Location, :community_tickets)
57
- )
127
+ location = Location.create!
128
+ ticket = CommunityTicket.create!
129
+ CardLocation.create! card: ticket, location: location
130
+
131
+ relation = Location.joins(ArelHelpers.join_association(Location, :community_tickets))
58
132
 
59
- relation.to_sql.should == 'SELECT "locations".* FROM "locations" ' +
60
- 'INNER JOIN "card_locations" ON "card_locations"."location_id" = "locations"."id" AND "card_locations"."card_type" = \'CommunityTicket\' ' +
61
- 'INNER JOIN "community_tickets" ON "community_tickets"."id" = "card_locations"."card_id"'
133
+ expect(relation.count).to eq 1
134
+ expect(relation.to_a).to include location
62
135
  end
63
136
  end
64
137
  end
@@ -68,8 +141,9 @@ describe ArelHelpers::JoinAssociation do
68
141
  include ArelHelpers::JoinAssociation
69
142
  end
70
143
 
71
- it "should provide the join_association method and use the parent class as the model to join on" do
72
- AssocPost.joins(AssocPost.join_association(:comments)).to_sql.should ==
73
- 'SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"'
144
+ it 'should provide the join_association method and use the parent class as the model to join on' do
145
+ expect(AssocPost.joins(AssocPost.join_association(:comments)).to_sql).to eq <<-SQL.squish
146
+ SELECT "posts".* FROM "posts" INNER JOIN "comments" ON "comments"."post_id" = "posts"."id"
147
+ SQL
74
148
  end
75
149
  end
@@ -1,8 +1,9 @@
1
- # encoding: UTF-8
2
-
3
1
  require 'spec_helper'
4
2
 
5
3
  class TestQueryBuilder < ArelHelpers::QueryBuilder
4
+ attr_accessor :params
5
+ alias_method :params?, :params
6
+
6
7
  def initialize(query = nil)
7
8
  super(query || Post.unscoped)
8
9
  end
@@ -10,45 +11,63 @@ class TestQueryBuilder < ArelHelpers::QueryBuilder
10
11
  def noop
11
12
  reflect(query)
12
13
  end
14
+
15
+ not_nil def optional(skip:)
16
+ reflect(query.where(title: 'BarBar')) unless skip
17
+ end
13
18
  end
14
19
 
15
20
  describe ArelHelpers::QueryBuilder do
16
21
  let(:builder) { TestQueryBuilder.new }
17
22
 
18
- it "returns (i.e. reflects) new instances of QueryBuilder" do
23
+ it 'returns (i.e. reflects) new instances of QueryBuilder' do
19
24
  builder.tap do |original_builder|
20
- original_builder.noop.object_id.should_not == original_builder.object_id
25
+ original_builder.params = true
26
+ new_builder = original_builder.noop
27
+ expect(new_builder.object_id).not_to eq original_builder.object_id
28
+ expect(new_builder.params?).to be true
21
29
  end
22
30
  end
23
31
 
24
- it "forwards #to_a" do
25
- Post.create(title: "Foobar")
32
+ it 'forwards #to_a' do
33
+ Post.create(title: 'Foobar')
26
34
  builder.to_a.tap do |posts|
27
- posts.size.should == 1
28
- posts.first.title.should == "Foobar"
35
+ expect(posts.size).to eq 1
36
+ expect(posts.first.title).to eq 'Foobar'
29
37
  end
30
38
  end
31
39
 
32
- it "forwards #to_sql" do
33
- builder.to_sql.strip.should == 'SELECT "posts".* FROM "posts"'
40
+ it 'forwards #to_sql' do
41
+ expect(builder.to_sql.strip).to eq 'SELECT "posts".* FROM "posts"'
34
42
  end
35
43
 
36
- it "forwards #each" do
37
- created_post = Post.create(title: "Foobar")
44
+ it 'forwards #each' do
45
+ created_post = Post.create(title: 'Foobar')
38
46
  builder.each do |post|
39
- post.should == created_post
47
+ expect(post).to eq created_post
40
48
  end
41
49
  end
42
50
 
43
- it "forwards other enumerable methods via #each" do
44
- Post.create(title: "Foobar")
45
- builder.map(&:title).should == ["Foobar"]
51
+ it 'forwards other enumerable methods via #each' do
52
+ Post.create(title: 'Foobar')
53
+ expect(builder.map(&:title)).to eq ['Foobar']
46
54
  end
47
55
 
48
56
  ArelHelpers::QueryBuilder::TERMINAL_METHODS.each do |method|
49
57
  it "does not enumerate records for #{method}" do
50
- mock(builder).each.never
58
+ allow(builder).to receive :each
51
59
  builder.public_send(method)
60
+ expect(builder).not_to have_received :each
52
61
  end
53
62
  end
63
+
64
+ it 'returns reflect on existing query if method returns a falsy value' do
65
+ expect(builder.optional(skip: true).to_sql.strip).to eq 'SELECT "posts".* FROM "posts"'
66
+ end
67
+
68
+ it 'returns reflect on new query for default chainable method if value is truthy' do
69
+ expect(builder.optional(skip: false).to_sql.strip.gsub(/\s+/, ' ')).to eq <<-SQL.squish
70
+ SELECT "posts".* FROM "posts" WHERE "posts"."title" = 'BarBar'
71
+ SQL
72
+ end
54
73
  end
data/spec/spec_helper.rb CHANGED
@@ -1,30 +1,20 @@
1
- # encoding: UTF-8
2
-
3
- $:.push(File.dirname(__FILE__))
1
+ $LOAD_PATH.push(File.dirname(__FILE__))
4
2
 
5
3
  require 'rspec'
6
4
  require 'arel-helpers'
7
5
  require 'fileutils'
8
- require 'pry-nav'
9
6
 
10
- require 'env'
7
+ require 'combustion'
8
+ Combustion.initialize! :active_record
11
9
 
12
- def silence(&block)
13
- original_stdout = $stdout
14
- $stdout = StringIO.new
15
- begin
16
- yield
17
- ensure
18
- $stdout = original_stdout
19
- end
20
- end
10
+ require 'database_cleaner'
11
+ require 'env/models'
21
12
 
22
13
  RSpec.configure do |config|
23
- config.mock_with :rr
14
+ DatabaseCleaner.strategy = :transaction
15
+
16
+ config.before(:suite) { DatabaseCleaner.clean_with :truncation }
24
17
 
25
- config.before(:each) do
26
- ArelHelpers::Env.establish_connection
27
- ArelHelpers::Env.reset
28
- silence { ArelHelpers::Env.migrate }
29
- end
18
+ config.before { DatabaseCleaner.start }
19
+ config.after { DatabaseCleaner.clean }
30
20
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: arel-helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.2.0
4
+ version: 2.12.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cameron Dutro
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-01-21 00:00:00.000000000 Z
11
+ date: 2020-12-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -19,7 +19,7 @@ dependencies:
19
19
  version: 3.1.0
20
20
  - - "<"
21
21
  - !ruby/object:Gem::Version
22
- version: '5'
22
+ version: '7'
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
@@ -29,7 +29,91 @@ dependencies:
29
29
  version: 3.1.0
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
- version: '5'
32
+ version: '7'
33
+ - !ruby/object:Gem::Dependency
34
+ name: appraisal
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: '0'
40
+ type: :development
41
+ prerelease: false
42
+ version_requirements: !ruby/object:Gem::Requirement
43
+ requirements:
44
+ - - ">="
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: combustion
49
+ requirement: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - "~>"
52
+ - !ruby/object:Gem::Version
53
+ version: '1.3'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - "~>"
59
+ - !ruby/object:Gem::Version
60
+ version: '1.3'
61
+ - !ruby/object:Gem::Dependency
62
+ name: database_cleaner
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: '1.8'
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: '1.8'
75
+ - !ruby/object:Gem::Dependency
76
+ name: rake
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "~>"
80
+ - !ruby/object:Gem::Version
81
+ version: '10.0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "~>"
87
+ - !ruby/object:Gem::Version
88
+ version: '10.0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rspec
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - "~>"
94
+ - !ruby/object:Gem::Version
95
+ version: '3'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - "~>"
101
+ - !ruby/object:Gem::Version
102
+ version: '3'
103
+ - !ruby/object:Gem::Dependency
104
+ name: sqlite3
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - "~>"
108
+ - !ruby/object:Gem::Version
109
+ version: 1.4.0
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - "~>"
115
+ - !ruby/object:Gem::Version
116
+ version: 1.4.0
33
117
  description: Useful tools to help construct database queries with ActiveRecord and
34
118
  Arel.
35
119
  email:
@@ -39,27 +123,31 @@ extensions: []
39
123
  extra_rdoc_files: []
40
124
  files:
41
125
  - Gemfile
42
- - History.txt
43
126
  - README.md
44
127
  - Rakefile
45
128
  - arel-helpers.gemspec
46
129
  - lib/arel-helpers.rb
130
+ - lib/arel-helpers/aliases.rb
47
131
  - lib/arel-helpers/arel_table.rb
48
132
  - lib/arel-helpers/ext/collection_proxy.rb
49
133
  - lib/arel-helpers/join_association.rb
50
134
  - lib/arel-helpers/query_builder.rb
51
135
  - lib/arel-helpers/version.rb
136
+ - spec/aliases_spec.rb
52
137
  - spec/arel_table_spec.rb
53
- - spec/env.rb
54
- - spec/env/migrations.rb
55
138
  - spec/env/models.rb
139
+ - spec/internal/config/database.yml
140
+ - spec/internal/db/combustion_test.sqlite
141
+ - spec/internal/db/schema.rb
142
+ - spec/internal/log/test.log
56
143
  - spec/join_association_spec.rb
57
144
  - spec/query_builder_spec.rb
58
145
  - spec/spec_helper.rb
59
- homepage: http://github.com/camertron
60
- licenses: []
146
+ homepage: https://github.com/camertron/arel-helpers
147
+ licenses:
148
+ - MIT
61
149
  metadata: {}
62
- post_install_message:
150
+ post_install_message:
63
151
  rdoc_options: []
64
152
  require_paths:
65
153
  - lib
@@ -74,9 +162,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
74
162
  - !ruby/object:Gem::Version
75
163
  version: '0'
76
164
  requirements: []
77
- rubyforge_project:
78
- rubygems_version: 2.2.3
79
- signing_key:
165
+ rubygems_version: 3.1.2
166
+ signing_key:
80
167
  specification_version: 4
81
168
  summary: Useful tools to help construct database queries with ActiveRecord and Arel.
82
169
  test_files: []