activerecord-precount 0.5.0 → 0.5.1
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.
- 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:
|