awesome_counter_cache 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a438135d0099fbe7652b5f754180b2f396650129a62066e364dee2fd69666bc4
4
+ data.tar.gz: 27ce6f7009265b2a1022793a1ff43af3e57a9f9dd6340d660299dbe1afbc78a1
5
+ SHA512:
6
+ metadata.gz: 1420eddc1824fc764e9f2a62a8d6464860366b945bd8112ef94d28082fd718cb6fecc617d32b7c50a67a9c0f5f79e593d007e1c2f3ec4e5609b34388cca3e6a7
7
+ data.tar.gz: ef5c2e47f810091cb35a302f1a738bbdf93336efb6a72969fc6116f0cdfc361cb4c103d13f6cfcc6f8ba809433c22243485246cd8b82be44347fd604a904de82
@@ -0,0 +1,20 @@
1
+ Copyright 2015 kaspernj
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,3 @@
1
+ # AwesomeCounterCache
2
+
3
+ This project rocks and uses MIT-LICENSE.
@@ -0,0 +1,17 @@
1
+ begin
2
+ require "bundler/setup"
3
+ rescue LoadError
4
+ puts "You must `gem install bundler` and `bundle install` to run rake tasks"
5
+ end
6
+
7
+ require "rdoc/task"
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = "rdoc"
11
+ rdoc.title = "AwesomeCounterCache"
12
+ rdoc.options << "--line-numbers"
13
+ rdoc.rdoc_files.include("README.rdoc")
14
+ rdoc.rdoc_files.include("lib/**/*.rb")
15
+ end
16
+
17
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,11 @@
1
+ module AwesomeCounterCache
2
+ extend ActiveSupport::Autoload
3
+
4
+ autoload :ClassMethods
5
+ autoload :InstanceMethods
6
+
7
+ def self.included(base)
8
+ base.extend AwesomeCounterCache::ClassMethods
9
+ base.include AwesomeCounterCache::InstanceMethods
10
+ end
11
+ end
@@ -0,0 +1,32 @@
1
+ module AwesomeCounterCache::ClassMethods
2
+ def awesome_counter_cache_for(relation_name, args = {})
3
+ id = awesome_counter_caches.length
4
+
5
+ args[:column_name] ||= "#{model_name.plural}_count"
6
+ args[:delta_magnitude] ||= proc { 1 }
7
+ args[:relation_name] = relation_name
8
+ args[:id] = id
9
+
10
+ awesome_counter_caches[id] = args
11
+
12
+ after_initialize do |model|
13
+ awesome_counter_cache_after_initialize(args, model)
14
+ end
15
+
16
+ after_commit on: :create do |model|
17
+ awesome_counter_cache_after_commit_on_create(args, model, relation_name)
18
+ end
19
+
20
+ after_commit on: :destroy do |model|
21
+ awesome_counter_cache_after_commit_on_destroy(args, model, relation_name)
22
+ end
23
+
24
+ after_commit on: :update do |model|
25
+ awesome_counter_cache_after_commit_on_update(args, model, relation_name)
26
+ end
27
+ end
28
+
29
+ def awesome_counter_caches
30
+ @awesome_counter_caches ||= {}
31
+ end
32
+ end
@@ -0,0 +1,85 @@
1
+ module AwesomeCounterCache::InstanceMethods
2
+ def awesome_counter_cache_after_commit_on_create(args, model, relation_name)
3
+ id = args.fetch(:id)
4
+ @awesome_counter_cache_data.fetch(id)[:delta_current] = args.fetch(:delta_magnitude).call(model)
5
+ model.create_awesome_counter_cache_for(relation_name, @awesome_counter_cache_data.fetch(id), args)
6
+ @awesome_counter_cache_data[id][:delta_original] = @awesome_counter_cache_data[id].delete(:delta_current)
7
+ end
8
+
9
+ def awesome_counter_cache_after_commit_on_destroy(args, model, relation_name)
10
+ id = args.fetch(:id)
11
+ @awesome_counter_cache_data.fetch(id)[:delta_current] = args.fetch(:delta_magnitude).call(model)
12
+ model.destroy_awesome_counter_cache_for(relation_name, @awesome_counter_cache_data.fetch(id), args)
13
+ @awesome_counter_cache_data[id][:delta_original] = @awesome_counter_cache_data[id].delete(:delta_current)
14
+ end
15
+
16
+ def awesome_counter_cache_after_commit_on_update(args, model, relation_name)
17
+ id = args.fetch(:id)
18
+ @awesome_counter_cache_data.fetch(id)[:delta_current] = args.fetch(:delta_magnitude).call(model)
19
+ model.update_awesome_counter_cache_for(relation_name, @awesome_counter_cache_data.fetch(id), args)
20
+ @awesome_counter_cache_data[id][:delta_original] = @awesome_counter_cache_data[id].delete(:delta_current)
21
+ end
22
+
23
+ def awesome_counter_cache_after_initialize(args, model)
24
+ id = args.fetch(:id)
25
+
26
+ @awesome_counter_cache_data ||= {}
27
+ @awesome_counter_cache_data[id] ||= {}
28
+
29
+ primary_key_column = self.class.primary_key
30
+
31
+ 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)[:delta_original] ||= 0
33
+ else
34
+ @awesome_counter_cache_data.fetch(id)[:delta_original] ||= args.fetch(:delta_magnitude).call(model)
35
+ end
36
+ end
37
+
38
+ def create_awesome_counter_cache_for(relation_name, state_data, args)
39
+ relation_model = __send__(relation_name)
40
+ return if relation_model.blank?
41
+
42
+ addition = state_data.fetch(:delta_current)
43
+
44
+ if addition != 0
45
+ primary_key_value = relation_model.read_attribute(relation_model.class.primary_key)
46
+ relation_model.class.update_counters(primary_key_value, args.fetch(:column_name) => addition)
47
+ end
48
+ end
49
+
50
+ def reload(*args, &blk)
51
+ result = super
52
+ awesome_counter_cache_reset_original_values
53
+ result
54
+ end
55
+
56
+ def awesome_counter_cache_reset_original_values
57
+ self.class.awesome_counter_caches.each do |id, args|
58
+ @awesome_counter_cache_data.fetch(id)[:delta_original] = args.fetch(:delta_magnitude).call(self)
59
+ end
60
+ end
61
+
62
+ def destroy_awesome_counter_cache_for(relation_name, state_data, args)
63
+ relation_model = __send__(relation_name)
64
+ return if relation_model.blank?
65
+
66
+ addition = -state_data.fetch(:delta_original)
67
+
68
+ if addition != 0
69
+ primary_key_value = relation_model.read_attribute(relation_model.class.primary_key)
70
+ relation_model.class.update_counters(primary_key_value, args.fetch(:column_name) => addition)
71
+ end
72
+ end
73
+
74
+ def update_awesome_counter_cache_for(relation_name, state_data, args)
75
+ relation_model = __send__(relation_name)
76
+ return if relation_model.blank?
77
+
78
+ addition = state_data.fetch(:delta_current) - state_data.fetch(:delta_original)
79
+
80
+ if addition != 0
81
+ primary_key_value = relation_model.read_attribute(relation_model.class.primary_key)
82
+ relation_model.class.update_counters(primary_key_value, args.fetch(:column_name) => addition)
83
+ end
84
+ end
85
+ end
@@ -0,0 +1,3 @@
1
+ module AwesomeCounterCache
2
+ VERSION = "0.0.1".freeze
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :awesome_counter_cache do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,169 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: awesome_counter_cache
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - kaspernj
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-02-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: factory_bot_rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: forgery
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry
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: rails
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: 5.0.0
62
+ - - "<"
63
+ - !ruby/object:Gem::Version
64
+ version: 7.0.0
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: 5.0.0
72
+ - - "<"
73
+ - !ruby/object:Gem::Version
74
+ version: 7.0.0
75
+ - !ruby/object:Gem::Dependency
76
+ name: rspec-rails
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - ">="
80
+ - !ruby/object:Gem::Version
81
+ version: '0'
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - ">="
87
+ - !ruby/object:Gem::Version
88
+ version: '0'
89
+ - !ruby/object:Gem::Dependency
90
+ name: rubocop
91
+ requirement: !ruby/object:Gem::Requirement
92
+ requirements:
93
+ - - ">="
94
+ - !ruby/object:Gem::Version
95
+ version: '0'
96
+ type: :development
97
+ prerelease: false
98
+ version_requirements: !ruby/object:Gem::Requirement
99
+ requirements:
100
+ - - ">="
101
+ - !ruby/object:Gem::Version
102
+ version: '0'
103
+ - !ruby/object:Gem::Dependency
104
+ name: sqlite3
105
+ requirement: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - ">="
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ type: :development
111
+ prerelease: false
112
+ version_requirements: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ - !ruby/object:Gem::Dependency
118
+ name: tzinfo-data
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ type: :development
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
131
+ description: Counter caching with a bit more for Rails
132
+ email:
133
+ - k@spernj.org
134
+ executables: []
135
+ extensions: []
136
+ extra_rdoc_files: []
137
+ files:
138
+ - MIT-LICENSE
139
+ - README.md
140
+ - Rakefile
141
+ - lib/awesome_counter_cache.rb
142
+ - lib/awesome_counter_cache/class_methods.rb
143
+ - lib/awesome_counter_cache/instance_methods.rb
144
+ - lib/awesome_counter_cache/version.rb
145
+ - lib/tasks/awesome_counter_cache_tasks.rake
146
+ homepage: https://github.com/kaspernj/awesome_counter_cache
147
+ licenses:
148
+ - MIT
149
+ metadata: {}
150
+ post_install_message:
151
+ rdoc_options: []
152
+ require_paths:
153
+ - lib
154
+ required_ruby_version: !ruby/object:Gem::Requirement
155
+ requirements:
156
+ - - ">="
157
+ - !ruby/object:Gem::Version
158
+ version: '0'
159
+ required_rubygems_version: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - ">="
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ requirements: []
165
+ rubygems_version: 3.0.6
166
+ signing_key:
167
+ specification_version: 4
168
+ summary: Counter caching with a bit more for Rails
169
+ test_files: []