counter_culture 2.2.1 → 2.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: ed37e7ce1d391b9fc468d8a1638b78e6afb46bc764dd7fff6935d00e41dbf18b
4
- data.tar.gz: 1a7d6b777a4065e214ebab7a25d271c4755eca109ca2907f71363450f329ff03
3
+ metadata.gz: c8c929583c30094df5eb38dce579819edf8e528fce64b06e3f5bddb95d5f2d13
4
+ data.tar.gz: 75a32b65babe86a8fef2d7aeb006b29db1c39210134b95c6854103eab72ee756
5
5
  SHA512:
6
- metadata.gz: '092c9686853ad23dea228cdd32ecef385efeeb3a43f55778372faaf052359512eaf82c7d2f68b1898d419f6911646e2024fde2d75706cefb339b7e98a3c125ce'
7
- data.tar.gz: cad2c4b3c7546d0a2098f3d738631712aaf80d26cf6244c7b27c53c3358fca7130e4e52c756e29c7b331549875cc063a7b28f1bc810f8556d73bb58ab4fd6cec
6
+ metadata.gz: 890a315177031dedb9d63ab8b2bb40887ec81ff240a11b323cf6bfb1287f16ab1c9cf479591a111562278e9e63fd840ea9751e486bbe7ef4ed58364c89bd7cd6
7
+ data.tar.gz: 8feec9380863959dbc3e362e31c0392d238508378f644335c6a10032fedb16641deaafea436442f231e9dc1b6bd917198251fb5bda85afc0aae2d1183b80f322
data/CHANGELOG.md CHANGED
@@ -1,3 +1,8 @@
1
+ ## 2.2.2 (May 5, 2019)
2
+
3
+ Bugfixes:
4
+ - Don't fail reconciliation in PostgreSQL if the Rails-level primary key is not a DB primary key (#254)
5
+
1
6
  ## 2.2.1 (April 17, 2019)
2
7
 
3
8
  Improvements:
data/README.md CHANGED
@@ -45,6 +45,8 @@ If you are adding counter caches to existing data, you must add code to [manuall
45
45
 
46
46
  ### Simple counter-cache
47
47
 
48
+ #### Has many association
49
+
48
50
  ```ruby
49
51
  class Product < ActiveRecord::Base
50
52
  belongs_to :category
@@ -58,6 +60,30 @@ end
58
60
 
59
61
  Now, the ```Category``` model will keep an up-to-date counter-cache in the ```products_count``` column of the ```categories``` table.
60
62
 
63
+ #### Many to many association
64
+
65
+ ```ruby
66
+ class User < ActiveRecord::Base
67
+ has_many :group_memberships
68
+ has_many :groups, through: :group_memberships
69
+ end
70
+
71
+ class Group < ActiveRecord::Base
72
+ has_many :group_memberships
73
+ has_many :members, through: :group_memberships, class: "User"
74
+ end
75
+
76
+ class Membership < ActiveRecord::Base
77
+ belongs_to :group
78
+ belongs_to :member, class: "User"
79
+ counter_cuture :group, column: "members_count"
80
+ # If you'd like to also touch the group when `members_count` is updated
81
+ # counter_culture :group, column: "members_count", touch: true
82
+ end
83
+ ```
84
+
85
+ Now, the `Group` model will have an up to date count of its members in the `members_count` column
86
+
61
87
  ### Multi-level counter-cache
62
88
 
63
89
  ```ruby
data/VERSION CHANGED
@@ -1 +1 @@
1
- 2.2.1
1
+ 2.2.2
@@ -2,16 +2,16 @@
2
2
  # DO NOT EDIT THIS FILE DIRECTLY
3
3
  # Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
4
4
  # -*- encoding: utf-8 -*-
5
- # stub: counter_culture 2.2.1 ruby lib
5
+ # stub: counter_culture 2.2.2 ruby lib
6
6
 
7
7
  Gem::Specification.new do |s|
8
8
  s.name = "counter_culture".freeze
9
- s.version = "2.2.1"
9
+ s.version = "2.2.2"
10
10
 
11
11
  s.required_rubygems_version = Gem::Requirement.new(">= 0".freeze) if s.respond_to? :required_rubygems_version=
12
12
  s.require_paths = ["lib".freeze]
13
13
  s.authors = ["Magnus von Koeller".freeze]
14
- s.date = "2019-04-17"
14
+ s.date = "2019-05-05"
15
15
  s.description = "counter_culture provides turbo-charged counter caches that are kept up-to-date not just on create and destroy, that support multiple levels of indirection through relationships, allow dynamic column names and that avoid deadlocks by updating in the after_commit callback.".freeze
16
16
  s.email = "magnus@vonkoeller.de".freeze
17
17
  s.extra_rdoc_files = [
@@ -47,6 +47,7 @@ Gem::Specification.new do |s|
47
47
  "spec/models/conditional_dependent.rb",
48
48
  "spec/models/conditional_main.rb",
49
49
  "spec/models/conversation.rb",
50
+ "spec/models/has_non_pk_id.rb",
50
51
  "spec/models/has_string_id.rb",
51
52
  "spec/models/industry.rb",
52
53
  "spec/models/person.rb",
@@ -87,7 +87,12 @@ module CounterCulture
87
87
  relation_class_table_name = quote_table_name(relation_class.table_name)
88
88
 
89
89
  # select join column and count (from above) as well as cache column ('column_name') for later comparison
90
- counts_query = scope.select("#{relation_class_table_name}.#{relation_class.primary_key}, #{relation_class_table_name}.#{relation_reflect(relation).association_primary_key(relation_class)}, #{count_select} AS count, #{relation_class_table_name}.#{column_name}")
90
+ counts_query = scope.select(
91
+ "#{relation_class_table_name}.#{relation_class.primary_key}, " \
92
+ "#{relation_class_table_name}.#{relation_reflect(relation).association_primary_key(relation_class)}, " \
93
+ "#{count_select} AS count, " \
94
+ "MAX(#{relation_class_table_name}.#{column_name}) AS #{column_name}"
95
+ )
91
96
 
92
97
  # we need to join together tables until we get back to the table this class itself lives in
93
98
  join_clauses(where).each do |join|
@@ -9,6 +9,7 @@ require 'models/twitter_review'
9
9
  require 'models/user'
10
10
  require 'models/category'
11
11
  require 'models/has_string_id'
12
+ require 'models/has_non_pk_id'
12
13
  require 'models/simple_main'
13
14
  require 'models/simple_dependent'
14
15
  require 'models/conditional_main'
@@ -1272,6 +1273,31 @@ describe "CounterCulture" do
1272
1273
  expect(string_id.users_count).to eq(2)
1273
1274
  end
1274
1275
 
1276
+ it "should fix a counter cache with no DB-level primary_key index correctly" do
1277
+ non_pk_id = HasNonPkId.create(id: (HasNonPkId.maximum(:id) || 1) + 1)
1278
+
1279
+ user = User.create(has_non_pk_id_id: non_pk_id.id)
1280
+
1281
+ non_pk_id.reload
1282
+ expect(non_pk_id.users_count).to eq(1)
1283
+
1284
+ user2 = User.create(has_non_pk_id_id: non_pk_id.id)
1285
+
1286
+ non_pk_id.reload
1287
+ expect(non_pk_id.users_count).to eq(2)
1288
+
1289
+ non_pk_id.users_count = 123
1290
+ non_pk_id.save!
1291
+
1292
+ non_pk_id.reload
1293
+ expect(non_pk_id.users_count).to eq(123)
1294
+
1295
+ User.counter_culture_fix_counts
1296
+
1297
+ non_pk_id.reload
1298
+ expect(non_pk_id.users_count).to eq(2)
1299
+ end
1300
+
1275
1301
  it "should fix a static delta magnitude column correctly" do
1276
1302
  user = User.create
1277
1303
  product = Product.create
@@ -0,0 +1,4 @@
1
+ class HasNonPkId < ActiveRecord::Base
2
+ self.primary_key = :id
3
+ has_many :users
4
+ end
data/spec/models/user.rb CHANGED
@@ -3,9 +3,13 @@ class User < ActiveRecord::Base
3
3
 
4
4
  belongs_to :manages_company, :class_name => "Company"
5
5
  counter_culture :manages_company, :column_name => "managers_count"
6
+
6
7
  belongs_to :has_string_id
7
8
  counter_culture :has_string_id
8
9
 
10
+ belongs_to :has_non_pk_id
11
+ counter_culture :has_non_pk_id
12
+
9
13
  has_many :reviews
10
14
  accepts_nested_attributes_for :reviews, :allow_destroy => true
11
15
 
@@ -15,7 +19,7 @@ class User < ActiveRecord::Base
15
19
 
16
20
  default_scope do
17
21
  if _default_scope_enabled
18
- query = joins("LEFT OUTER JOIN companies")
22
+ query = joins("LEFT OUTER JOIN companies ON users.company_id = companies.id")
19
23
  if Rails.version < "5.0.0"
20
24
  query = query.uniq
21
25
  else
data/spec/schema.rb CHANGED
@@ -79,6 +79,7 @@ ActiveRecord::Schema.define(:version => 20120522160158) do
79
79
  t.integer "custom_delta_count", :default => 0, :null => false
80
80
  t.integer "review_approvals_count", :default => 0, :null => false
81
81
  t.string "has_string_id_id"
82
+ t.integer "has_non_pk_id_id"
82
83
  t.float "review_value_sum", :default => 0.0, :null => false
83
84
  t.datetime "created_at"
84
85
  t.datetime "updated_at"
@@ -92,6 +93,15 @@ ActiveRecord::Schema.define(:version => 20120522160158) do
92
93
  t.datetime "updated_at"
93
94
  end
94
95
 
96
+ create_table "has_non_pk_ids", :force => true, :id => false do |t|
97
+ t.integer "id", :default => '', :null => false
98
+ t.string "something"
99
+ t.integer "users_count", :null => false, :default => 0
100
+ t.datetime "created_at"
101
+ t.datetime "updated_at"
102
+ end
103
+ add_index "has_non_pk_ids", :id, :unique => true
104
+
95
105
  create_table "has_string_ids", :force => true, :id => false do |t|
96
106
  t.string "id", :default => '', :null => false
97
107
  t.string "something"
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.2.1
4
+ version: 2.2.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Magnus von Koeller
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-04-17 00:00:00.000000000 Z
11
+ date: 2019-05-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: after_commit_action
@@ -245,6 +245,7 @@ files:
245
245
  - spec/models/conditional_dependent.rb
246
246
  - spec/models/conditional_main.rb
247
247
  - spec/models/conversation.rb
248
+ - spec/models/has_non_pk_id.rb
248
249
  - spec/models/has_string_id.rb
249
250
  - spec/models/industry.rb
250
251
  - spec/models/person.rb