activerecord-precount 0.5.0 → 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -0
- data/activerecord-precount.gemspec +1 -1
- data/lib/active_record/precount/has_many_extension.rb +1 -1
- data/lib/active_record/precount/relation_extension.rb +4 -2
- data/lib/active_record/precount/version.rb +1 -1
- data/test/cases/associations/eager_count_test.rb +15 -7
- data/test/cases/associations/eager_load_test.rb +13 -5
- data/test/cases/associations/includes_test.rb +12 -4
- data/test/cases/associations/precount_test.rb +15 -7
- data/test/cases/associations/preload_test.rb +12 -4
- data/test/models/tweet.rb +2 -0
- metadata +10 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b966bc8459e4470af32e26fa47a9b1c23c0ca2f5
|
4
|
+
data.tar.gz: 8a036719d57f1a1e4978c6655473e3c6b8112219
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb7d18f68c02a4c30b33ac1b64ef44f26e430b03ca46a6fe58342220dd3c4f88b1185eab3e1c69dc34169dcbd4f6cc98979a2a7386e118369502706bade6d3dd
|
7
|
+
data.tar.gz: ee694266b59423dd92a44600c9588adb26416950211c5e7ccaf8ecc00bda0253f080b73df124c37744cf0d54d08fc576f5e518863ecd6fbdf672252e4e293533
|
data/.travis.yml
CHANGED
@@ -24,7 +24,7 @@ Gem::Specification.new do |spec|
|
|
24
24
|
spec.add_development_dependency "bundler"
|
25
25
|
spec.add_development_dependency "pry"
|
26
26
|
spec.add_development_dependency "sqlite3"
|
27
|
-
spec.add_development_dependency "mysql2"
|
27
|
+
spec.add_development_dependency "mysql2", ">= 0.3", "< 0.4"
|
28
28
|
spec.add_development_dependency "postgres"
|
29
29
|
spec.add_development_dependency "rbench"
|
30
30
|
spec.add_development_dependency "dalli"
|
@@ -16,7 +16,7 @@ module ActiveRecord
|
|
16
16
|
name_with_count = options[:count_loader] if options[:count_loader].is_a?(Symbol)
|
17
17
|
|
18
18
|
valid_options = options.slice(*Associations::Builder::CountLoader.valid_options)
|
19
|
-
reflection = Associations::Builder::CountLoader.build(model, name_with_count,
|
19
|
+
reflection = Associations::Builder::CountLoader.build(model, name_with_count, scope, valid_options)
|
20
20
|
Reflection.add_reflection(model, name_with_count, reflection)
|
21
21
|
end
|
22
22
|
end
|
@@ -32,8 +32,10 @@ module ActiveRecord
|
|
32
32
|
raise ArgumentError, "Association named '#{arg}' was not found on #{klass.name}." unless has_reflection?(arg)
|
33
33
|
next if has_reflection?(counter_name = :"#{arg}_count")
|
34
34
|
|
35
|
-
|
36
|
-
|
35
|
+
original_reflection = reflection_for(arg)
|
36
|
+
scope = original_reflection.scope
|
37
|
+
options = original_reflection.options.slice(*Associations::Builder::CountLoader.valid_options)
|
38
|
+
reflection = Associations::Builder::CountLoader.build(klass, counter_name, scope, options)
|
37
39
|
Reflection.add_reflection(model, counter_name, reflection)
|
38
40
|
end
|
39
41
|
end
|
@@ -2,9 +2,11 @@ require 'cases/helper'
|
|
2
2
|
|
3
3
|
class EagerCountTest < ActiveRecord::CountLoader::TestCase
|
4
4
|
def setup
|
5
|
-
tweets_count.times
|
5
|
+
tweets_count.times do |i|
|
6
6
|
tweet = Tweet.create
|
7
|
-
|
7
|
+
i.times do |j|
|
8
|
+
Favorite.create(tweet: tweet, user_id: j + 1)
|
9
|
+
end
|
8
10
|
end
|
9
11
|
|
10
12
|
if Tweet.has_reflection?(:favs_count)
|
@@ -25,9 +27,9 @@ class EagerCountTest < ActiveRecord::CountLoader::TestCase
|
|
25
27
|
end
|
26
28
|
|
27
29
|
def test_eager_count_defines_count_loader
|
28
|
-
assert_equal(Tweet.has_reflection?(:favs_count)
|
30
|
+
assert_equal(false, Tweet.has_reflection?(:favs_count))
|
29
31
|
Tweet.eager_count(:favs).map(&:favs_count)
|
30
|
-
assert_equal(Tweet.has_reflection?(:favs_count)
|
32
|
+
assert_equal(true, Tweet.has_reflection?(:favs_count))
|
31
33
|
end
|
32
34
|
|
33
35
|
def test_eager_count_has_many_with_count_loader_does_not_execute_n_1_queries
|
@@ -39,8 +41,14 @@ class EagerCountTest < ActiveRecord::CountLoader::TestCase
|
|
39
41
|
|
40
42
|
def test_eager_count_has_many_counts_properly
|
41
43
|
expected = Tweet.order(id: :asc).map { |t| t.favorites.count }
|
42
|
-
assert_equal(Tweet.order(id: :asc).map(&:favorites_count)
|
43
|
-
assert_equal(Tweet.order(id: :asc).eager_count(:favorites).map { |t| t.favorites.count }
|
44
|
-
assert_equal(Tweet.order(id: :asc).eager_count(:favorites).map(&:favorites_count)
|
44
|
+
assert_equal(expected, Tweet.order(id: :asc).map(&:favorites_count))
|
45
|
+
assert_equal(expected, Tweet.order(id: :asc).eager_count(:favorites).map { |t| t.favorites.count })
|
46
|
+
assert_equal(expected, Tweet.order(id: :asc).eager_count(:favorites).map(&:favorites_count))
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_eager_count_has_many_with_scope_counts_properly
|
50
|
+
expected = Tweet.order(id: :asc).map { |t| t.my_favs.count }
|
51
|
+
assert_equal(expected, Tweet.order(id: :asc).eager_count(:my_favs).map { |t| t.my_favs.count })
|
52
|
+
assert_equal(expected, Tweet.order(id: :asc).eager_count(:my_favs).map(&:my_favs_count))
|
45
53
|
end
|
46
54
|
end
|
@@ -4,9 +4,11 @@ require 'models/tweet'
|
|
4
4
|
|
5
5
|
class EagerLoadTest < ActiveRecord::CountLoader::TestCase
|
6
6
|
def setup
|
7
|
-
tweets_count.times
|
7
|
+
tweets_count.times do |i|
|
8
8
|
tweet = Tweet.create
|
9
|
-
|
9
|
+
i.times do |j|
|
10
|
+
Favorite.create(tweet: tweet, user_id: j + 1)
|
11
|
+
end
|
10
12
|
end
|
11
13
|
end
|
12
14
|
|
@@ -26,8 +28,14 @@ class EagerLoadTest < ActiveRecord::CountLoader::TestCase
|
|
26
28
|
|
27
29
|
def test_eager_loaded_count_loader_counts_properly
|
28
30
|
expected = Tweet.order(id: :asc).map { |t| t.favorites.count }
|
29
|
-
assert_equal(Tweet.order(id: :asc).map(&:favorites_count)
|
30
|
-
assert_equal(Tweet.order(id: :asc).eager_load(:favorites_count).map { |t| t.favorites.count }
|
31
|
-
assert_equal(Tweet.order(id: :asc).eager_load(:favorites_count).map(&:favorites_count)
|
31
|
+
assert_equal(expected, Tweet.order(id: :asc).map(&:favorites_count))
|
32
|
+
assert_equal(expected, Tweet.order(id: :asc).eager_load(:favorites_count).map { |t| t.favorites.count })
|
33
|
+
assert_equal(expected, Tweet.order(id: :asc).eager_load(:favorites_count).map(&:favorites_count))
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_eager_loaded_count_loader_with_scope_counts_properly
|
37
|
+
expected = Tweet.order(id: :asc).map { |t| t.my_favorites.count }
|
38
|
+
assert_equal(expected, Tweet.order(id: :asc).eager_load(:my_favorites_count).map { |t| t.my_favorites.count })
|
39
|
+
assert_equal(expected, Tweet.order(id: :asc).eager_load(:my_favorites_count).map(&:my_favorites_count))
|
32
40
|
end
|
33
41
|
end
|
@@ -2,9 +2,11 @@ require 'cases/helper'
|
|
2
2
|
|
3
3
|
class IncludesTest < ActiveRecord::CountLoader::TestCase
|
4
4
|
def setup
|
5
|
-
tweets_count.times
|
5
|
+
tweets_count.times do |i|
|
6
6
|
tweet = Tweet.create
|
7
|
-
|
7
|
+
i.times do |j|
|
8
|
+
Favorite.create(tweet: tweet, user_id: j + 1)
|
9
|
+
end
|
8
10
|
end
|
9
11
|
end
|
10
12
|
|
@@ -24,7 +26,13 @@ class IncludesTest < ActiveRecord::CountLoader::TestCase
|
|
24
26
|
|
25
27
|
def test_included_count_loader_counts_properly
|
26
28
|
expected = Tweet.all.map { |t| t.favorites.count }
|
27
|
-
assert_equal(Tweet.all.map(&:favorites_count)
|
28
|
-
assert_equal(Tweet.includes(:favorites_count).map(&:favorites_count)
|
29
|
+
assert_equal(expected, Tweet.all.map(&:favorites_count))
|
30
|
+
assert_equal(expected, Tweet.includes(:favorites_count).map(&:favorites_count))
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_included_count_loader_with_scope_counts_properly
|
34
|
+
expected = Tweet.all.map { |t| t.my_favorites.count }
|
35
|
+
assert_equal(expected, Tweet.all.map(&:my_favorites_count))
|
36
|
+
assert_equal(expected, Tweet.includes(:my_favorites_count).map(&:my_favorites_count))
|
29
37
|
end
|
30
38
|
end
|
@@ -2,9 +2,11 @@ require 'cases/helper'
|
|
2
2
|
|
3
3
|
class PrecountTest < ActiveRecord::CountLoader::TestCase
|
4
4
|
def setup
|
5
|
-
tweets_count.times
|
5
|
+
tweets_count.times do |i|
|
6
6
|
tweet = Tweet.create
|
7
|
-
|
7
|
+
i.times do |j|
|
8
|
+
Favorite.create(tweet: tweet, user_id: j + 1)
|
9
|
+
end
|
8
10
|
end
|
9
11
|
|
10
12
|
if Tweet.has_reflection?(:favs_count)
|
@@ -25,9 +27,9 @@ class PrecountTest < ActiveRecord::CountLoader::TestCase
|
|
25
27
|
end
|
26
28
|
|
27
29
|
def test_precount_defines_count_loader
|
28
|
-
assert_equal(Tweet.has_reflection?(:favs_count)
|
30
|
+
assert_equal(false, Tweet.has_reflection?(:favs_count))
|
29
31
|
Tweet.precount(:favs).map(&:favs_count)
|
30
|
-
assert_equal(Tweet.has_reflection?(:favs_count)
|
32
|
+
assert_equal(true, Tweet.has_reflection?(:favs_count))
|
31
33
|
end
|
32
34
|
|
33
35
|
def test_precount_has_many_with_count_loader_does_not_execute_n_1_queries
|
@@ -39,8 +41,14 @@ class PrecountTest < ActiveRecord::CountLoader::TestCase
|
|
39
41
|
|
40
42
|
def test_precount_has_many_counts_properly
|
41
43
|
expected = Tweet.all.map { |t| t.favorites.count }
|
42
|
-
assert_equal(Tweet.all.map(&:favorites_count)
|
43
|
-
assert_equal(Tweet.precount(:favorites).map { |t| t.favorites.count }
|
44
|
-
assert_equal(Tweet.precount(:favorites).map(&:favorites_count)
|
44
|
+
assert_equal(expected, Tweet.all.map(&:favorites_count))
|
45
|
+
assert_equal(expected, Tweet.precount(:favorites).map { |t| t.favorites.count })
|
46
|
+
assert_equal(expected, Tweet.precount(:favorites).map(&:favorites_count))
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_precount_has_many_with_scope_counts_properly
|
50
|
+
expected = Tweet.all.map { |t| t.my_favs.count }
|
51
|
+
assert_equal(expected, Tweet.precount(:my_favs).map { |t| t.my_favs.count })
|
52
|
+
assert_equal(expected, Tweet.precount(:my_favs).map(&:my_favs_count))
|
45
53
|
end
|
46
54
|
end
|
@@ -2,9 +2,11 @@ require 'cases/helper'
|
|
2
2
|
|
3
3
|
class PreloadTest < ActiveRecord::CountLoader::TestCase
|
4
4
|
def setup
|
5
|
-
tweets_count.times
|
5
|
+
tweets_count.times do |i|
|
6
6
|
tweet = Tweet.create
|
7
|
-
|
7
|
+
i.times do |j|
|
8
|
+
Favorite.create(tweet: tweet, user_id: j + 1)
|
9
|
+
end
|
8
10
|
end
|
9
11
|
end
|
10
12
|
|
@@ -24,7 +26,13 @@ class PreloadTest < ActiveRecord::CountLoader::TestCase
|
|
24
26
|
|
25
27
|
def test_preloaded_count_loader_counts_properly
|
26
28
|
expected = Tweet.all.map { |t| t.favorites.count }
|
27
|
-
assert_equal(Tweet.all.map(&:favorites_count)
|
28
|
-
assert_equal(Tweet.preload(:favorites_count).map(&:favorites_count)
|
29
|
+
assert_equal(expected, Tweet.all.map(&:favorites_count))
|
30
|
+
assert_equal(expected, Tweet.preload(:favorites_count).map(&:favorites_count))
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_preloaded_count_loader_with_scope_counts_properly
|
34
|
+
expected = Tweet.all.map { |t| t.my_favorites.count }
|
35
|
+
assert_equal(expected, Tweet.all.map(&:my_favorites_count))
|
36
|
+
assert_equal(expected, Tweet.preload(:my_favorites_count).map(&:my_favorites_count))
|
29
37
|
end
|
30
38
|
end
|
data/test/models/tweet.rb
CHANGED
@@ -1,4 +1,6 @@
|
|
1
1
|
class Tweet < ActiveRecord::Base
|
2
2
|
has_many :favorites, count_loader: true
|
3
3
|
has_many :favs, class_name: 'Favorite'
|
4
|
+
has_many :my_favorites, -> { where(user_id: 1) }, class_name: 'Favorite', count_loader: true
|
5
|
+
has_many :my_favs, -> { where(user_id: 1) }, class_name: 'Favorite'
|
4
6
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-precount
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.5.
|
4
|
+
version: 0.5.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Takashi Kokubun
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -114,14 +114,20 @@ dependencies:
|
|
114
114
|
requirements:
|
115
115
|
- - ">="
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: '0'
|
117
|
+
version: '0.3'
|
118
|
+
- - "<"
|
119
|
+
- !ruby/object:Gem::Version
|
120
|
+
version: '0.4'
|
118
121
|
type: :development
|
119
122
|
prerelease: false
|
120
123
|
version_requirements: !ruby/object:Gem::Requirement
|
121
124
|
requirements:
|
122
125
|
- - ">="
|
123
126
|
- !ruby/object:Gem::Version
|
124
|
-
version: '0'
|
127
|
+
version: '0.3'
|
128
|
+
- - "<"
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: '0.4'
|
125
131
|
- !ruby/object:Gem::Dependency
|
126
132
|
name: postgres
|
127
133
|
requirement: !ruby/object:Gem::Requirement
|
@@ -292,4 +298,3 @@ signing_key:
|
|
292
298
|
specification_version: 4
|
293
299
|
summary: N+1 count query killer for ActiveRecord
|
294
300
|
test_files: []
|
295
|
-
has_rdoc:
|