counter_culture 2.7.0 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 74fff95505913ba522b3ec93bc9101c375c7de5678744145a0e4959f2c267361
4
- data.tar.gz: bc284f87da6f949e7d875b7f30c43accbe23ce5716601af9fc4143eb6346954d
3
+ metadata.gz: dd2787a78c042c84c8585261e4fb2f2975fd5688833de084e6936cb605fd85d6
4
+ data.tar.gz: dc42bb90b178eca596a17ceb0455ea8cd499d615f66f585a357ed3d6584987fa
5
5
  SHA512:
6
- metadata.gz: e63708745c4ffbb727a1b4da61a0d027de76d7256ee5d9669fa0f18dfcc2b183f26ddc109f45d6af6fb68a79c040e73872f647e8453c7b801e390036601878eb
7
- data.tar.gz: c58c36d4aaf450450d913ad93487c7012de5de0ba8bb4f99c83a3994b64e8aed19f04a0d62c0df21ceda862312b9c010af042857709d891f746e20403ef893f2
6
+ metadata.gz: b015b805b60250331318aa8e0c66b8f313e1b6e9f7da3d8dbee966463b2b7c15adc6be042f572fa0a6fe0df0baf323219eb1aaf2bd2c4df8d4519c929d089bdc
7
+ data.tar.gz: 00b1cd20630a952f7dd435da9fff6ef9700f3c9dd2e8330a180bb0c4768aede7ca718e7dfbf0a61df5c9c6cd169c43551c6970a8cf70d186a9b4ae940df4e300
data/.travis.yml CHANGED
@@ -1,31 +1,42 @@
1
1
  language: ruby
2
+ cache:
3
+ directories:
4
+ - ~/.rvm/gems
2
5
  services:
3
6
  - postgresql
4
7
  - mysql
5
8
  addons:
6
9
  postgresql: "9.6"
7
10
  rvm:
8
- - "2.5.7"
9
- - "2.6.5"
10
- - "2.7.0"
11
+ - "2.5.8"
12
+ - "2.6.6"
13
+ - "2.7.2"
14
+ - "3.0.0"
11
15
  gemfile:
12
16
  - gemfiles/rails_4.2.gemfile
13
17
  - gemfiles/rails_5.0.gemfile
14
18
  - gemfiles/rails_5.1.gemfile
15
19
  - gemfiles/rails_5.2.gemfile
16
20
  - gemfiles/rails_6.0.gemfile
21
+ - gemfiles/rails_6.1.gemfile
17
22
  matrix:
18
23
  exclude:
19
- - rvm: "2.7.0"
24
+ - rvm: "3.0.0"
20
25
  gemfile: gemfiles/rails_4.2.gemfile
26
+ - rvm: "3.0.0"
27
+ gemfile: gemfiles/rails_5.0.gemfile
28
+ - rvm: "3.0.0"
29
+ gemfile: gemfiles/rails_5.1.gemfile
30
+ - rvm: "3.0.0"
31
+ gemfile: gemfiles/rails_5.2.gemfile
21
32
  env:
22
33
  - DB=postgresql
23
34
  - DB=sqlite3
24
35
  - DB=mysql2
25
36
  before_install:
26
- - gem install bundler -v '1.17.3'
37
+ - if [ "$BUNDLE_GEMFILE" = "$PWD/gemfiles/rails_4.2.gemfile" ]; then gem install bundler -v '1.17.3'; else gem install bundler -v '> 2'; fi
27
38
  install:
28
- - bundle _1.17.3_ update
39
+ - if [ "$BUNDLE_GEMFILE" = "$PWD/gemfiles/rails_4.2.gemfile" ]; then bundle _1.17.3_ update; else bundle update; fi
29
40
  before_script:
30
41
  - psql -c 'create database counter_culture_test;' -U postgres
31
42
  - mysql -e 'CREATE DATABASE counter_culture_test;'
data/Appraisals CHANGED
@@ -4,6 +4,7 @@
4
4
  5.1
5
5
  5.2
6
6
  6.0
7
+ 6.1
7
8
  ].each do |rails_version|
8
9
  gem_rails_version = Gem::Version.new(rails_version)
9
10
  if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.5.0') &&
@@ -15,8 +16,19 @@
15
16
  appraise "rails-#{rails_version}" do
16
17
  gem 'rails', "~> #{rails_version}.0"
17
18
 
18
- gem 'pg', gem_rails_version < Gem::Version.new('5.0') ? '~> 0.15' : '~> 1.0'
19
+ if gem_rails_version < Gem::Version.new('5.0')
20
+ gem 'pg', '~> 0.15'
21
+ else
22
+ gem 'pg'
23
+ end
19
24
  gem 'mysql2'
20
- gem 'sqlite3', gem_rails_version < Gem::Version.new(5.2) ? '~> 1.3.0' : '~> 1.4'
25
+ if gem_rails_version < Gem::Version.new('5.2')
26
+ gem 'sqlite3', '~> 1.3.0'
27
+ else
28
+ gem 'sqlite3'
29
+ end
30
+ if gem_rails_version < Gem::Version.new('5.0')
31
+ gem 'bigdecimal', '~> 1.3.5'
32
+ end
21
33
  end
22
34
  end
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 2.8.0 (March 16, 2021)
2
+
3
+ Improvements:
4
+ - New `execute_after_commit` option (#309)
5
+
1
6
  ## 2.7.0 (November 16, 2020)
2
7
 
3
8
  Improvements:
data/README.md CHANGED
@@ -7,7 +7,7 @@ Turbo-charged counter caches for your Rails app. Huge improvements over the Rail
7
7
  * Supports dynamic column names, making it possible to split up the counter cache for different types of objects
8
8
  * Can keep a running count, or a running total
9
9
 
10
- Tested against Ruby 2.3.8, 2.4.7, 2.5.6 and 2.6.4 and against the latest patch releases of Rails 4.2, 5.0, 5.1, 5.2 and 6.0.
10
+ Tested against Ruby 2.5.8, 2.6.6, 2.7.2 and 3.0.0, and against the latest patch releases of Rails 4.2, 5.0, 5.1, 5.2, 6.0 and 6.1.
11
11
 
12
12
  Please note that -- unlike Rails' built-in counter-caches -- counter_culture does not currently change the behavior of the `.size` method on ActiveRecord associations. If you want to avoid a database query and read the cached value, please use the attribute name containing the counter cache directly.
13
13
  ```
@@ -250,6 +250,16 @@ You may also specify a custom timestamp column that gets updated only when a par
250
250
 
251
251
  With this option, any time the `category_counter_cache` changes both the `category_count_changed` and `updated_at` columns will get updated.
252
252
 
253
+ ### Avoiding deadlocks / executing counter cache updates after commit
254
+
255
+ Some applications run into issues with deadlocks involving counter cache updates when using this gem. See [#263](https://github.com/magnusvk/counter_culture/issues/263#issuecomment-772284439) for information and helpful links on how to avoid this issue.
256
+
257
+ Another option is to simply defer the update of counter caches to outside of the transaction. This gives up transacrtional guarantees for your counter cache updates but should resolve any deadlocks you experience. This behavior is disabled by default, enable it on each affected counter cache as follows:
258
+
259
+ ```ruby
260
+ counter_culture :category, execute_after_commit: true
261
+ ```
262
+
253
263
  ### Manually populating counter cache values
254
264
 
255
265
  You will sometimes want to populate counter-cache values from primary data. This is required when adding counter-caches to existing data. It is also recommended to run this regularly (at BestVendor, we run it once a week) to catch any incorrect values in the counter caches.
@@ -446,4 +456,4 @@ counter_culture now supports polymorphic associations of one level only.
446
456
 
447
457
  ## Copyright
448
458
 
449
- Copyright (c) 2012-2013 BestVendor, Magnus von Koeller. See LICENSE.txt for further details.
459
+ Copyright (c) 2012-2021 BestVendor, Magnus von Koeller. See LICENSE.txt for further details.
@@ -30,11 +30,12 @@ Gem::Specification.new do |spec|
30
30
 
31
31
  spec.add_development_dependency 'appraisal', '> 2.0.0'
32
32
  spec.add_development_dependency 'awesome_print'
33
- spec.add_development_dependency 'bundler', '~> 1.17'
33
+ spec.add_development_dependency 'bundler'
34
34
  spec.add_development_dependency 'database_cleaner', '>= 1.1.1'
35
35
  spec.add_development_dependency 'discard'
36
36
  spec.add_development_dependency 'paper_trail'
37
37
  spec.add_development_dependency 'paranoia'
38
+ spec.add_development_dependency 'after_commit_action'
38
39
  spec.add_development_dependency 'rails', '>= 4.2'
39
40
  spec.add_development_dependency 'rake', '>= 10.0'
40
41
  spec.add_development_dependency 'rdoc', '~> 5.0.0'
@@ -6,5 +6,6 @@ gem "sqlite3", "~> 1.3.0"
6
6
  gem "rails", "~> 4.2.0"
7
7
  gem "pg", "~> 0.15"
8
8
  gem "mysql2"
9
+ gem "bigdecimal", "~> 1.3.5"
9
10
 
10
11
  gemspec path: "../"
@@ -4,7 +4,7 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "sqlite3", "~> 1.3.0"
6
6
  gem "rails", "~> 5.0.0"
7
- gem "pg", "~> 1.0"
7
+ gem "pg"
8
8
  gem "mysql2"
9
9
 
10
10
  gemspec path: "../"
@@ -4,7 +4,7 @@ source "https://rubygems.org"
4
4
 
5
5
  gem "sqlite3", "~> 1.3.0"
6
6
  gem "rails", "~> 5.1.0"
7
- gem "pg", "~> 1.0"
7
+ gem "pg"
8
8
  gem "mysql2"
9
9
 
10
10
  gemspec path: "../"
@@ -2,9 +2,9 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "sqlite3", "~> 1.4"
5
+ gem "sqlite3"
6
6
  gem "rails", "~> 5.2.0"
7
- gem "pg", "~> 1.0"
7
+ gem "pg"
8
8
  gem "mysql2"
9
9
 
10
10
  gemspec path: "../"
@@ -2,9 +2,9 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "sqlite3", "~> 1.4"
5
+ gem "sqlite3"
6
6
  gem "rails", "~> 6.0.0"
7
- gem "pg", "~> 1.0"
7
+ gem "pg"
8
8
  gem "mysql2"
9
9
 
10
10
  gemspec path: "../"
@@ -0,0 +1,10 @@
1
+ # This file was generated by Appraisal
2
+
3
+ source "https://rubygems.org"
4
+
5
+ gem "sqlite3"
6
+ gem "rails", "~> 6.1.0"
7
+ gem "pg"
8
+ gem "mysql2"
9
+
10
+ gemspec path: "../"
@@ -1,6 +1,6 @@
1
1
  module CounterCulture
2
2
  class Counter
3
- CONFIG_OPTIONS = [ :column_names, :counter_cache_name, :delta_column, :foreign_key_values, :touch, :delta_magnitude]
3
+ CONFIG_OPTIONS = [ :column_names, :counter_cache_name, :delta_column, :foreign_key_values, :touch, :delta_magnitude, :execute_after_commit ]
4
4
  ACTIVE_RECORD_VERSION = Gem.loaded_specs["activerecord"].version
5
5
 
6
6
  attr_reader :model, :relation, *CONFIG_OPTIONS
@@ -9,10 +9,6 @@ module CounterCulture
9
9
  @model = model
10
10
  @relation = relation.is_a?(Enumerable) ? relation : [relation]
11
11
 
12
- if options.fetch(:execute_after_commit, false)
13
- fail("execute_after_commit was removed; updates now run within the transaction")
14
- end
15
-
16
12
  @counter_cache_name = options.fetch(:column_name, "#{model.name.demodulize.tableize}_count")
17
13
  @column_names = options[:column_names]
18
14
  @delta_column = options[:delta_column]
@@ -20,6 +16,18 @@ module CounterCulture
20
16
  @touch = options.fetch(:touch, false)
21
17
  @delta_magnitude = options[:delta_magnitude] || 1
22
18
  @with_papertrail = options.fetch(:with_papertrail, false)
19
+ @execute_after_commit = options.fetch(:execute_after_commit, false)
20
+
21
+ if @execute_after_commit
22
+ begin
23
+ require 'after_commit_action'
24
+ rescue LoadError
25
+ fail(LoadError.new(
26
+ "You need to include the `after_commit_action` gem in your "\
27
+ "gem dependencies to use the execute_after_commit option"))
28
+ end
29
+ model.include(AfterCommitAction)
30
+ end
23
31
  end
24
32
 
25
33
  # increments or decrements a counter cache
@@ -93,14 +101,20 @@ module CounterCulture
93
101
  instance.send("#{timestamp_column}=", current_time)
94
102
  end
95
103
 
96
- instance.paper_trail.save_with_version(validate: false)
104
+ execute_now_or_after_commit(obj) do
105
+ instance.paper_trail.save_with_version(validate: false)
106
+ end
97
107
  else
98
- instance.paper_trail.touch_with_version
108
+ execute_now_or_after_commit(obj) do
109
+ instance.paper_trail.touch_with_version
110
+ end
99
111
  end
100
112
  end
101
113
  end
102
114
 
103
- klass.where(primary_key => id_to_change).update_all updates.join(', ')
115
+ execute_now_or_after_commit(obj) do
116
+ klass.where(primary_key => id_to_change).update_all updates.join(', ')
117
+ end
104
118
  end
105
119
  end
106
120
 
@@ -296,6 +310,14 @@ module CounterCulture
296
310
  prev
297
311
  end
298
312
 
313
+ def execute_now_or_after_commit(obj, &block)
314
+ if @execute_after_commit
315
+ obj.execute_after_commit(&block)
316
+ else
317
+ block.call
318
+ end
319
+ end
320
+
299
321
  private
300
322
  def attribute_was(obj, attr)
301
323
  changes_method =
@@ -1,3 +1,3 @@
1
1
  module CounterCulture
2
- VERSION = '2.7.0'.freeze
2
+ VERSION = '2.8.0'.freeze
3
3
  end
data/run_tests_locally.sh CHANGED
@@ -3,7 +3,7 @@
3
3
  set -e
4
4
  source /usr/local/share/chruby/chruby.sh
5
5
 
6
- for RUBY_VERSION in 2.5.7 2.6.5 2.7.0; do
6
+ for RUBY_VERSION in 2.5.8 2.6.6 2.7.2 3.0.0; do
7
7
  chruby $RUBY_VERSION
8
8
  ruby --version
9
9
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: counter_culture
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.0
4
+ version: 2.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Magnus von Koeller
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-11-16 00:00:00.000000000 Z
11
+ date: 2021-03-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -70,16 +70,16 @@ dependencies:
70
70
  name: bundler
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - "~>"
73
+ - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '1.17'
75
+ version: '0'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - "~>"
80
+ - - ">="
81
81
  - !ruby/object:Gem::Version
82
- version: '1.17'
82
+ version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: database_cleaner
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -136,6 +136,20 @@ dependencies:
136
136
  - - ">="
137
137
  - !ruby/object:Gem::Version
138
138
  version: '0'
139
+ - !ruby/object:Gem::Dependency
140
+ name: after_commit_action
141
+ requirement: !ruby/object:Gem::Requirement
142
+ requirements:
143
+ - - ">="
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ type: :development
147
+ prerelease: false
148
+ version_requirements: !ruby/object:Gem::Requirement
149
+ requirements:
150
+ - - ">="
151
+ - !ruby/object:Gem::Version
152
+ version: '0'
139
153
  - !ruby/object:Gem::Dependency
140
154
  name: rails
141
155
  requirement: !ruby/object:Gem::Requirement
@@ -263,6 +277,7 @@ files:
263
277
  - gemfiles/rails_5.1.gemfile
264
278
  - gemfiles/rails_5.2.gemfile
265
279
  - gemfiles/rails_6.0.gemfile
280
+ - gemfiles/rails_6.1.gemfile
266
281
  - lib/counter_culture.rb
267
282
  - lib/counter_culture/counter.rb
268
283
  - lib/counter_culture/extensions.rb