awesome_counter_cache 0.0.1 → 0.0.2
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/README.md +7 -1
- data/lib/awesome_counter_cache/class_methods.rb +10 -6
- data/lib/awesome_counter_cache/counter_cache.rb +11 -0
- data/lib/awesome_counter_cache/instance_methods.rb +56 -37
- data/lib/awesome_counter_cache/state.rb +3 -0
- data/lib/awesome_counter_cache/version.rb +1 -1
- data/lib/awesome_counter_cache.rb +2 -0
- metadata +78 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: da9f3b10f0b3d3f91d23585c3cbb6234b585987d7d4ba4704026de6871830e66
|
4
|
+
data.tar.gz: '09a7a1388a4d93709e10712d8dd3d8a9c7ad0af76a456d4b2b2b674a1f697d6b'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 635c8b6ba277428198ab978addf81aa9723b713d26f4dcf6a6a26bdc84ef84a444c7450be3cb4b1419afbb699be7f60fbaafcca92a7c8bb328f5d794cfcd274b
|
7
|
+
data.tar.gz: ccd61848475acd36066de42204772e0ea8d0778e4a4ebda7b7dc26f3fe1de0f13cdc4f91d083e63a770a2df61328b2ddfe15cc15049a04e805f20fa1d703ba8e
|
data/README.md
CHANGED
@@ -1,28 +1,32 @@
|
|
1
1
|
module AwesomeCounterCache::ClassMethods
|
2
2
|
def awesome_counter_cache_for(relation_name, args = {})
|
3
3
|
id = awesome_counter_caches.length
|
4
|
-
|
5
4
|
args[:column_name] ||= "#{model_name.plural}_count"
|
6
5
|
args[:delta_magnitude] ||= proc { 1 }
|
6
|
+
args[:relation_foreign_key] = reflections.fetch(relation_name.to_s).foreign_key
|
7
7
|
args[:relation_name] = relation_name
|
8
8
|
args[:id] = id
|
9
9
|
|
10
|
-
|
10
|
+
counter_cache = AwesomeCounterCache::CounterCache.new(**args)
|
11
|
+
awesome_counter_caches[id] = counter_cache
|
12
|
+
awesome_counter_cache_init_callbacks(counter_cache)
|
13
|
+
end
|
11
14
|
|
15
|
+
def awesome_counter_cache_init_callbacks(counter_cache)
|
12
16
|
after_initialize do |model|
|
13
|
-
awesome_counter_cache_after_initialize(
|
17
|
+
awesome_counter_cache_after_initialize(counter_cache, model)
|
14
18
|
end
|
15
19
|
|
16
20
|
after_commit on: :create do |model|
|
17
|
-
awesome_counter_cache_after_commit_on_create(
|
21
|
+
awesome_counter_cache_after_commit_on_create(counter_cache, model)
|
18
22
|
end
|
19
23
|
|
20
24
|
after_commit on: :destroy do |model|
|
21
|
-
awesome_counter_cache_after_commit_on_destroy(
|
25
|
+
awesome_counter_cache_after_commit_on_destroy(counter_cache, model)
|
22
26
|
end
|
23
27
|
|
24
28
|
after_commit on: :update do |model|
|
25
|
-
awesome_counter_cache_after_commit_on_update(
|
29
|
+
awesome_counter_cache_after_commit_on_update(counter_cache, model)
|
26
30
|
end
|
27
31
|
end
|
28
32
|
|
@@ -0,0 +1,11 @@
|
|
1
|
+
class AwesomeCounterCache::CounterCache
|
2
|
+
attr_accessor :column_name, :delta_magnitude, :id, :relation_foreign_key, :relation_name
|
3
|
+
|
4
|
+
def initialize(column_name:, delta_magnitude:, id:, relation_foreign_key:, relation_name:)
|
5
|
+
@column_name = column_name
|
6
|
+
@delta_magnitude = delta_magnitude
|
7
|
+
@id = id
|
8
|
+
@relation_foreign_key = relation_foreign_key
|
9
|
+
@relation_name = relation_name
|
10
|
+
end
|
11
|
+
end
|
@@ -1,49 +1,55 @@
|
|
1
1
|
module AwesomeCounterCache::InstanceMethods
|
2
|
-
def awesome_counter_cache_after_commit_on_create(
|
3
|
-
id =
|
4
|
-
@awesome_counter_cache_data.fetch(id)
|
5
|
-
|
6
|
-
|
2
|
+
def awesome_counter_cache_after_commit_on_create(counter_cache, model)
|
3
|
+
id = counter_cache.id
|
4
|
+
state = @awesome_counter_cache_data.fetch(id)
|
5
|
+
state.delta_current = counter_cache.delta_magnitude.call(model)
|
6
|
+
model.create_awesome_counter_cache_for(counter_cache.relation_name, @awesome_counter_cache_data.fetch(id), counter_cache)
|
7
|
+
state.delta_original = state.delta_current
|
8
|
+
state.delta_current = nil
|
7
9
|
end
|
8
10
|
|
9
|
-
def awesome_counter_cache_after_commit_on_destroy(
|
10
|
-
id =
|
11
|
-
@awesome_counter_cache_data.fetch(id)
|
12
|
-
|
13
|
-
|
11
|
+
def awesome_counter_cache_after_commit_on_destroy(counter_cache, model)
|
12
|
+
id = counter_cache.id
|
13
|
+
state = @awesome_counter_cache_data.fetch(id)
|
14
|
+
state.delta_current = counter_cache.delta_magnitude.call(model)
|
15
|
+
model.destroy_awesome_counter_cache_for(counter_cache.relation_name, @awesome_counter_cache_data.fetch(id), counter_cache)
|
16
|
+
state.delta_original = state.delta_current
|
17
|
+
state.delta_current = nil
|
14
18
|
end
|
15
19
|
|
16
|
-
def awesome_counter_cache_after_commit_on_update(
|
17
|
-
id =
|
18
|
-
@awesome_counter_cache_data.fetch(id)
|
19
|
-
|
20
|
-
|
20
|
+
def awesome_counter_cache_after_commit_on_update(counter_cache, model)
|
21
|
+
id = counter_cache.id
|
22
|
+
state = @awesome_counter_cache_data.fetch(id)
|
23
|
+
state.delta_current = counter_cache.delta_magnitude.call(model)
|
24
|
+
model.update_awesome_counter_cache_for(counter_cache.relation_name, @awesome_counter_cache_data.fetch(id), counter_cache)
|
25
|
+
state.delta_original = state.delta_current
|
26
|
+
state.delta_current = nil
|
21
27
|
end
|
22
28
|
|
23
|
-
def awesome_counter_cache_after_initialize(
|
24
|
-
id =
|
29
|
+
def awesome_counter_cache_after_initialize(counter_cache, model)
|
30
|
+
id = counter_cache.id
|
25
31
|
|
26
32
|
@awesome_counter_cache_data ||= {}
|
27
|
-
@awesome_counter_cache_data[id] ||=
|
33
|
+
@awesome_counter_cache_data[id] ||= AwesomeCounterCache::State.new
|
28
34
|
|
29
35
|
primary_key_column = self.class.primary_key
|
30
36
|
|
31
37
|
if read_attribute(primary_key_column).nil? # `new_record?` always returns false so check if primary key is nil instead - kaspernj
|
32
|
-
@awesome_counter_cache_data.fetch(id)
|
38
|
+
@awesome_counter_cache_data.fetch(id).delta_original ||= 0
|
33
39
|
else
|
34
|
-
@awesome_counter_cache_data.fetch(id)
|
40
|
+
@awesome_counter_cache_data.fetch(id).delta_original ||= counter_cache.delta_magnitude.call(model)
|
35
41
|
end
|
36
42
|
end
|
37
43
|
|
38
|
-
def create_awesome_counter_cache_for(relation_name,
|
44
|
+
def create_awesome_counter_cache_for(relation_name, state, counter_cache)
|
39
45
|
relation_model = __send__(relation_name)
|
40
46
|
return if relation_model.blank?
|
41
47
|
|
42
|
-
addition =
|
48
|
+
addition = state.delta_current
|
43
49
|
|
44
50
|
if addition != 0
|
45
51
|
primary_key_value = relation_model.read_attribute(relation_model.class.primary_key)
|
46
|
-
relation_model.class.update_counters(primary_key_value,
|
52
|
+
relation_model.class.update_counters(primary_key_value, counter_cache.column_name => addition) # rubocop:disable Rails/SkipsModelValidations
|
47
53
|
end
|
48
54
|
end
|
49
55
|
|
@@ -54,32 +60,45 @@ module AwesomeCounterCache::InstanceMethods
|
|
54
60
|
end
|
55
61
|
|
56
62
|
def awesome_counter_cache_reset_original_values
|
57
|
-
self.class.awesome_counter_caches.each do |id,
|
58
|
-
@awesome_counter_cache_data.fetch(id)
|
63
|
+
self.class.awesome_counter_caches.each do |id, counter_cache|
|
64
|
+
state = @awesome_counter_cache_data.fetch(id)
|
65
|
+
state.delta_original = counter_cache.delta_magnitude.call(self)
|
59
66
|
end
|
60
67
|
end
|
61
68
|
|
62
|
-
def destroy_awesome_counter_cache_for(relation_name,
|
69
|
+
def destroy_awesome_counter_cache_for(relation_name, state, counter_cache)
|
63
70
|
relation_model = __send__(relation_name)
|
64
71
|
return if relation_model.blank?
|
65
72
|
|
66
|
-
addition = -
|
73
|
+
addition = -state.delta_original
|
67
74
|
|
68
75
|
if addition != 0
|
69
76
|
primary_key_value = relation_model.read_attribute(relation_model.class.primary_key)
|
70
|
-
relation_model.class.update_counters(primary_key_value,
|
77
|
+
relation_model.class.update_counters(primary_key_value, counter_cache.column_name => addition) # rubocop:disable Rails/SkipsModelValidations
|
71
78
|
end
|
72
79
|
end
|
73
80
|
|
74
|
-
def update_awesome_counter_cache_for(relation_name,
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
81
|
+
def update_awesome_counter_cache_for(relation_name, state, counter_cache) # rubocop:disable Metrics/AbcSize
|
82
|
+
addition = state.delta_current - state.delta_original
|
83
|
+
relation_model_class = self.class.reflections.fetch(relation_name.to_s).klass
|
84
|
+
primary_key_value = read_attribute(counter_cache.relation_foreign_key)
|
85
|
+
|
86
|
+
if saved_changes.key?(counter_cache.relation_foreign_key)
|
87
|
+
# Record change from one to another - reduce and increase based on previously recorded values
|
88
|
+
old_record_id = saved_changes.fetch(counter_cache.relation_foreign_key).first
|
89
|
+
|
90
|
+
if old_record_id && !state.delta_original.zero?
|
91
|
+
# Reduce the count of the previous record
|
92
|
+
relation_model_class.update_counters(old_record_id, counter_cache.column_name => -state.delta_original) # rubocop:disable Rails/SkipsModelValidations
|
93
|
+
end
|
94
|
+
|
95
|
+
unless state.delta_current.zero?
|
96
|
+
# Increase the count of the new record
|
97
|
+
relation_model_class.update_counters(primary_key_value, counter_cache.column_name => state.delta_current) # rubocop:disable Rails/SkipsModelValidations
|
98
|
+
end
|
99
|
+
elsif !addition.zero?
|
100
|
+
# Add to the current record
|
101
|
+
relation_model_class.update_counters(primary_key_value, counter_cache.column_name => addition) # rubocop:disable Rails/SkipsModelValidations
|
83
102
|
end
|
84
103
|
end
|
85
104
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: awesome_counter_cache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- kaspernj
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-06-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: factory_bot_rails
|
@@ -38,6 +38,34 @@ dependencies:
|
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: mysql2
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pg
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
41
69
|
- !ruby/object:Gem::Dependency
|
42
70
|
name: pry
|
43
71
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,6 +128,48 @@ dependencies:
|
|
100
128
|
- - ">="
|
101
129
|
- !ruby/object:Gem::Version
|
102
130
|
version: '0'
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
name: rubocop-performance
|
133
|
+
requirement: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - ">="
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: '0'
|
138
|
+
type: :development
|
139
|
+
prerelease: false
|
140
|
+
version_requirements: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - ">="
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: '0'
|
145
|
+
- !ruby/object:Gem::Dependency
|
146
|
+
name: rubocop-rails
|
147
|
+
requirement: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
type: :development
|
153
|
+
prerelease: false
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
159
|
+
- !ruby/object:Gem::Dependency
|
160
|
+
name: rubocop-rspec
|
161
|
+
requirement: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - ">="
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - ">="
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: '0'
|
103
173
|
- !ruby/object:Gem::Dependency
|
104
174
|
name: sqlite3
|
105
175
|
requirement: !ruby/object:Gem::Requirement
|
@@ -140,13 +210,16 @@ files:
|
|
140
210
|
- Rakefile
|
141
211
|
- lib/awesome_counter_cache.rb
|
142
212
|
- lib/awesome_counter_cache/class_methods.rb
|
213
|
+
- lib/awesome_counter_cache/counter_cache.rb
|
143
214
|
- lib/awesome_counter_cache/instance_methods.rb
|
215
|
+
- lib/awesome_counter_cache/state.rb
|
144
216
|
- lib/awesome_counter_cache/version.rb
|
145
217
|
- lib/tasks/awesome_counter_cache_tasks.rake
|
146
218
|
homepage: https://github.com/kaspernj/awesome_counter_cache
|
147
219
|
licenses:
|
148
220
|
- MIT
|
149
|
-
metadata:
|
221
|
+
metadata:
|
222
|
+
rubygems_mfa_required: 'true'
|
150
223
|
post_install_message:
|
151
224
|
rdoc_options: []
|
152
225
|
require_paths:
|
@@ -155,14 +228,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
155
228
|
requirements:
|
156
229
|
- - ">="
|
157
230
|
- !ruby/object:Gem::Version
|
158
|
-
version:
|
231
|
+
version: 2.5.0
|
159
232
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
160
233
|
requirements:
|
161
234
|
- - ">="
|
162
235
|
- !ruby/object:Gem::Version
|
163
236
|
version: '0'
|
164
237
|
requirements: []
|
165
|
-
rubygems_version: 3.0.
|
238
|
+
rubygems_version: 3.0.8
|
166
239
|
signing_key:
|
167
240
|
specification_version: 4
|
168
241
|
summary: Counter caching with a bit more for Rails
|