association_count 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +3 -0
- data/.travis.yml +1 -0
- data/CHANGELOG.md +13 -0
- data/LICENSE.txt +1 -1
- data/README.md +25 -3
- data/association_count.gemspec +2 -1
- data/lib/association_count.rb +46 -10
- data/lib/association_count/version.rb +1 -1
- metadata +9 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: 42248c2a05d75c6ee5a6b9959fe8c5687210802a93163c7e984b8ee2415b87ec
|
4
|
+
data.tar.gz: 6ddaa4c21d1c0289e3199aa1fcdf1faec9236908ffb1ae7f171ba993450774da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 99e29c73a3c6afc83a220bae9b67a2b842795595712ce80ef63ae8de5b99a52499f1624d24314e0b1e8983068f961d777c3fa58e33cef98918730cbf23a9321c
|
7
|
+
data.tar.gz: 55f58a8be27457398bf68ecaad839fb5508c48dcefc479b49d59ae2c398d0e78e83d9dadf9b874509a0f25ecac1575cf170cc5f68582c79a51a4c023fab48e1f
|
data/.gitignore
CHANGED
data/.travis.yml
CHANGED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# HEAD
|
2
|
+
|
3
|
+
## v1.1
|
4
|
+
|
5
|
+
- :warning: _Breaking change/Bug fix_: Move from `joins` to `left_outer_joins` by default, see [PR#3](https://github.com/buren/association_count/pull/3)
|
6
|
+
+ You can still configure it to use `joins` by default - see [README](README,md)
|
7
|
+
- Configure options globally, per model or per method call
|
8
|
+
|
9
|
+
---
|
10
|
+
|
11
|
+
# v1.0
|
12
|
+
|
13
|
+
..is history
|
data/LICENSE.txt
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c)
|
3
|
+
Copyright (c) 2018 Jacob Burenstam Linder, Albin Svensson
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
# AssociationCount [![Build Status](https://travis-ci.org/buren/association_count.svg?branch=master)](https://travis-ci.org/buren/association_count)
|
2
2
|
|
3
|
+
Get ActiveRecord association count with ease and without worrying about N+1 queries:
|
4
|
+
```ruby
|
5
|
+
Author.all.include_post_count.map(&:post_count)
|
6
|
+
```
|
7
|
+
|
3
8
|
A small gem for ActiveRecord that allows association counts to be included in your base query.
|
4
9
|
|
5
10
|
## Installation
|
@@ -50,6 +55,7 @@ Rails 4, add it to `ActiveRecord::Base`
|
|
50
55
|
ActiveRecord::Base.extend AssociationCount
|
51
56
|
```
|
52
57
|
|
58
|
+
Full example
|
53
59
|
```ruby
|
54
60
|
class Foo < ActiveRecord::Base
|
55
61
|
has_many :bars
|
@@ -69,12 +75,28 @@ foos = Foo.all.association_count(Bar)
|
|
69
75
|
|
70
76
|
This works for any `has_many` relationship even if it uses non standard foreign keys or is a `has_many :x, through: y`.
|
71
77
|
|
72
|
-
By default
|
78
|
+
:information_source: By default we will use left outer join and __not__ distinct.
|
73
79
|
|
74
|
-
|
80
|
+
You can configure this on per model basis
|
81
|
+
```ruby
|
75
82
|
class Foo < ActiveRecord::Base
|
76
83
|
has_many :bars
|
77
|
-
can_count :bars, distinct:
|
84
|
+
can_count :bars, distinct: true, join_type: :joins # can also be left_outer_joins
|
85
|
+
end
|
86
|
+
```
|
87
|
+
|
88
|
+
or on a case by case basis
|
89
|
+
|
90
|
+
```ruby
|
91
|
+
Foo.all.include_bar_count(distinct: false, join_type: :left_outer_joins)
|
92
|
+
```
|
93
|
+
|
94
|
+
## Configuration
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
AssociationCount.configure do |config|
|
98
|
+
config.distinct = false
|
99
|
+
config.join_type = :joins # or left_outer_joins
|
78
100
|
end
|
79
101
|
```
|
80
102
|
|
data/association_count.gemspec
CHANGED
@@ -8,7 +8,8 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = AssociationCount::VERSION
|
9
9
|
spec.authors = ['Albin Svensson', 'Jacob Burenstam']
|
10
10
|
spec.email = ['burenstam@gmail.com']
|
11
|
-
spec.summary = '
|
11
|
+
spec.summary = 'Get an ActiveRecord association count with ease and without worrying about N+1 queries.'
|
12
|
+
spec.description = 'Get an ActiveRecord association count with ease and without worrying about N+1 queries. A small gem for ActiveRecord that allows association counts to be included in your base query.'
|
12
13
|
spec.homepage = 'https://github.com/buren/association_count'
|
13
14
|
spec.license = 'MIT'
|
14
15
|
|
data/lib/association_count.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
require 'association_count/version'
|
2
2
|
|
3
3
|
module AssociationCount
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
def association_count(
|
5
|
+
counted_model,
|
6
|
+
distinct: AssociationCount.config.distinct,
|
7
|
+
join_type: AssociationCount.config.join_type
|
8
|
+
)
|
7
9
|
table_name = self.table_name
|
8
10
|
counted_table = counted_model.table_name
|
9
11
|
counted_name = counted_table.singularize
|
10
12
|
distinct_sql = distinct ? 'DISTINCT' : ''
|
11
13
|
|
12
|
-
|
14
|
+
public_send(join_type, counted_table.to_sym)
|
13
15
|
.select("#{table_name}.*, COUNT(#{distinct_sql} #{counted_table}.id) as #{counted_name}_count_raw")
|
14
16
|
.group("#{table_name}.id")
|
15
17
|
end
|
@@ -17,13 +19,16 @@ module AssociationCount
|
|
17
19
|
def can_count(model_name, opts = {})
|
18
20
|
model_name = model_name.to_s
|
19
21
|
reflection = reflections[model_name]
|
20
|
-
|
22
|
+
raise ArgumentError, "No such reflection: '#{model_name}'" unless reflection
|
21
23
|
|
22
|
-
options
|
24
|
+
options = {
|
25
|
+
distinct: AssociationCount.config.distinct,
|
26
|
+
join_type: AssociationCount.config.join_type
|
27
|
+
}.merge!(opts)
|
23
28
|
singular_name = model_name.singularize
|
24
29
|
|
25
30
|
define_association_count_method(model_name, singular_name)
|
26
|
-
define_count_scope(singular_name, reflection, options[:distinct])
|
31
|
+
define_count_scope(singular_name, reflection, options[:distinct], options[:join_type])
|
27
32
|
end
|
28
33
|
|
29
34
|
def define_association_count_method(model_name, singular_name)
|
@@ -34,12 +39,43 @@ module AssociationCount
|
|
34
39
|
end
|
35
40
|
end
|
36
41
|
|
37
|
-
def define_count_scope(singular_name, reflection, default_distinct)
|
42
|
+
def define_count_scope(singular_name, reflection, default_distinct, default_join_type)
|
38
43
|
scope_name = "include_#{singular_name}_count"
|
39
44
|
class_eval do
|
40
|
-
scope scope_name, ->(distinct: default_distinct) {
|
41
|
-
association_count(reflection.klass, distinct: distinct)
|
45
|
+
scope scope_name, ->(distinct: default_distinct, join_type: default_join_type) {
|
46
|
+
association_count(reflection.klass, distinct: distinct, join_type: join_type)
|
42
47
|
}
|
43
48
|
end
|
44
49
|
end
|
50
|
+
|
51
|
+
def self.configuration
|
52
|
+
@configuration ||= Configuration.new
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.config
|
56
|
+
configuration
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.configure
|
60
|
+
yield(configuration) if block_given?
|
61
|
+
configuration
|
62
|
+
end
|
63
|
+
|
64
|
+
class Configuration
|
65
|
+
attr_accessor :distinct
|
66
|
+
attr_reader :join_type
|
67
|
+
|
68
|
+
def initialize
|
69
|
+
@distinct = false
|
70
|
+
@join_type = :left_outer_joins
|
71
|
+
end
|
72
|
+
|
73
|
+
def join_type=(type)
|
74
|
+
type = type.to_sym
|
75
|
+
unless %i[left_outer_joins joins].include?(type)
|
76
|
+
raise(ArgumentError, "unknown join type '#{type}', must be one of left_outer_joins, joins")
|
77
|
+
end
|
78
|
+
@join_type = type.to_sym
|
79
|
+
end
|
80
|
+
end
|
45
81
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: association_count
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Albin Svensson
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: exe
|
11
11
|
cert_chain: []
|
12
|
-
date: 2018-
|
12
|
+
date: 2018-09-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -123,7 +123,9 @@ dependencies:
|
|
123
123
|
- - ">="
|
124
124
|
- !ruby/object:Gem::Version
|
125
125
|
version: '4.0'
|
126
|
-
description:
|
126
|
+
description: Get an ActiveRecord association count with ease and without worrying
|
127
|
+
about N+1 queries. A small gem for ActiveRecord that allows association counts to
|
128
|
+
be included in your base query.
|
127
129
|
email:
|
128
130
|
- burenstam@gmail.com
|
129
131
|
executables: []
|
@@ -133,6 +135,7 @@ files:
|
|
133
135
|
- ".gitignore"
|
134
136
|
- ".rspec"
|
135
137
|
- ".travis.yml"
|
138
|
+
- CHANGELOG.md
|
136
139
|
- Gemfile
|
137
140
|
- Guardfile
|
138
141
|
- LICENSE.txt
|
@@ -163,9 +166,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
163
166
|
version: '0'
|
164
167
|
requirements: []
|
165
168
|
rubyforge_project:
|
166
|
-
rubygems_version: 2.6
|
169
|
+
rubygems_version: 2.7.6
|
167
170
|
signing_key:
|
168
171
|
specification_version: 4
|
169
|
-
summary:
|
170
|
-
|
172
|
+
summary: Get an ActiveRecord association count with ease and without worrying about
|
173
|
+
N+1 queries.
|
171
174
|
test_files: []
|