arel-helpers 2.2.0 → 2.12.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.
@@ -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: []