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 +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +26 -0
- data/VERSION +1 -1
- data/counter_culture.gemspec +4 -3
- data/lib/counter_culture/reconciler.rb +6 -1
- data/spec/counter_culture_spec.rb +26 -0
- data/spec/models/has_non_pk_id.rb +4 -0
- data/spec/models/user.rb +5 -1
- data/spec/schema.rb +10 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: c8c929583c30094df5eb38dce579819edf8e528fce64b06e3f5bddb95d5f2d13
|
|
4
|
+
data.tar.gz: 75a32b65babe86a8fef2d7aeb006b29db1c39210134b95c6854103eab72ee756
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 890a315177031dedb9d63ab8b2bb40887ec81ff240a11b323cf6bfb1287f16ab1c9cf479591a111562278e9e63fd840ea9751e486bbe7ef4ed58364c89bd7cd6
|
|
7
|
+
data.tar.gz: 8feec9380863959dbc3e362e31c0392d238508378f644335c6a10032fedb16641deaafea436442f231e9dc1b6bd917198251fb5bda85afc0aae2d1183b80f322
|
data/CHANGELOG.md
CHANGED
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
|
+
2.2.2
|
data/counter_culture.gemspec
CHANGED
|
@@ -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.
|
|
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.
|
|
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-
|
|
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(
|
|
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
|
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.
|
|
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-
|
|
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
|