activerecord-cached_at 2.0.4 → 2.0.5
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
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7b3d64e5e2adb795b942f664462d24ed6ed4d7f2
|
4
|
+
data.tar.gz: 95bef73c44b5dc5a34d066326a0f143e71a6aed1
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a3cb5c3704956ee085247bbbf12f504feba96eed6604cdf73488055acbf71479d9e91e838433320a22ad14c1cd3b60fade816d7170809036814c7cf4bb60321b
|
7
|
+
data.tar.gz: ae7d263524467b04d8d90687f392a2e7db39714282e73f9bd8b89ab69f0b245c9f72c02289d848ba6e523ab8d0ea5d8628b72b09419ea2a4019bd302ba1b121f
|
@@ -0,0 +1,15 @@
|
|
1
|
+
module CachedAt
|
2
|
+
module AssociationExtension
|
3
|
+
|
4
|
+
def self.build(model, reflection)
|
5
|
+
return unless reflection.options[:cached_at]
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.valid_options
|
9
|
+
[:cached_at]
|
10
|
+
end
|
11
|
+
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
ActiveRecord::Associations::Builder::Association.extensions << CachedAt::AssociationExtension
|
@@ -29,53 +29,38 @@ module CachedAt
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
32
|
-
|
33
|
-
def
|
34
|
-
return if owner.new_record? || records.empty?
|
35
|
-
|
36
|
-
if reflection.options[:cached_at]
|
37
|
-
if reflection.inverse_of.nil?
|
38
|
-
puts "WARNING: cannot updated cached at for relationship: #{klass.name}.#{name}, inverse_of not set"
|
39
|
-
return
|
40
|
-
end
|
41
|
-
|
42
|
-
cache_column = "#{reflection.inverse_of.name}_cached_at"
|
43
|
-
if loaded?
|
44
|
-
target.each { |r| r.raw_write_attribute(cache_column, timestamp) }
|
45
|
-
end
|
46
|
-
|
47
|
-
ids = records.inject([]) { |a, o| a += [o.send(klass.primary_key), o.send("#{klass.primary_key}_was")] }.compact.uniq
|
48
|
-
query = klass.where(klass.primary_key => ids)
|
49
|
-
query.update_all({ cache_column => timestamp })
|
50
|
-
traverse_relationships(klass, reflection.options[:cached_at], query, cache_column, timestamp)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def touch_records_removed_cached_at(records, timestamp)
|
55
|
-
return if owner.new_record? || records.empty?
|
56
|
-
|
32
|
+
|
33
|
+
def touch_records_cached_at(records, timestamp)
|
57
34
|
return unless options[:cached_at]
|
58
35
|
|
59
36
|
if reflection.inverse_of.nil?
|
60
|
-
puts "WARNING: cannot updated cached at for relationship: #{
|
37
|
+
puts "WARNING: cannot updated cached at for relationship: #{owner.class.name}.#{name}, inverse_of not set"
|
61
38
|
return
|
62
39
|
end
|
63
|
-
|
40
|
+
|
64
41
|
cache_column = "#{reflection.inverse_of.name}_cached_at"
|
65
|
-
|
66
|
-
|
67
|
-
|
42
|
+
|
43
|
+
records.each { |r| r.raw_write_attribute(cache_column, timestamp) unless r.destroyed? }
|
44
|
+
|
45
|
+
query = klass.where({ klass.primary_key => records.map(&:id) })
|
46
|
+
query.update_all({ cache_column => timestamp })
|
47
|
+
traverse_relationships(klass, options[:cached_at], query, cache_column, timestamp)
|
68
48
|
end
|
69
|
-
|
70
|
-
def
|
49
|
+
|
50
|
+
def add_to_target(record, skip_callbacks = false, &block)
|
71
51
|
value = super
|
72
|
-
|
52
|
+
touch_records_cached_at([record], Time.now) if !(instance_variable_defined?(:@caching) && @caching)
|
73
53
|
value
|
74
54
|
end
|
75
|
-
|
76
|
-
def
|
77
|
-
|
78
|
-
|
55
|
+
|
56
|
+
def replace_records(new_target, original_target)
|
57
|
+
@caching = true
|
58
|
+
changed_records = (target - new_target) | (new_target - target)
|
59
|
+
value = super
|
60
|
+
touch_records_cached_at(changed_records, Time.now) unless owner.new_record?
|
61
|
+
value
|
62
|
+
ensure
|
63
|
+
@caching = false
|
79
64
|
end
|
80
65
|
|
81
66
|
def delete_all(dependent = nil)
|
@@ -5,97 +5,56 @@ module CachedAt
|
|
5
5
|
using_reflection = reflection.parent_reflection || reflection
|
6
6
|
return unless using_reflection.options[:cached_at]
|
7
7
|
|
8
|
+
return if method == :create && !using_reflection.is_a?(ActiveRecord::Reflection::HasAndBelongsToManyReflection)
|
9
|
+
|
8
10
|
if using_reflection.inverse_of.nil?
|
9
11
|
puts "WARNING: cannot updated cached at for relationship: #{owner.class.name}.#{using_reflection.name}, inverse_of not set"
|
10
12
|
return
|
11
13
|
end
|
12
14
|
|
13
15
|
cache_column = "#{using_reflection.inverse_of.name}_cached_at"
|
14
|
-
ids = [owner.send(using_reflection.association_primary_key), owner.send("#{using_reflection.association_primary_key}_was")].compact.uniq
|
15
|
-
|
16
|
-
|
17
|
-
arel_table = klass._reflections[using_reflection.inverse_of.options[:through].to_s].klass.arel_table
|
18
|
-
query = klass.joins(using_reflection.inverse_of.options[:through])
|
19
|
-
query = if using_reflection.is_a?(ActiveRecord::Reflection::HasAndBelongsToManyReflection)
|
20
|
-
query.where(arel_table[using_reflection.foreign_key].in(ids))
|
21
|
-
else
|
22
|
-
query.where(arel_table[using_reflection.inverse_of.foreign_key].in(ids))
|
23
|
-
end
|
24
16
|
|
17
|
+
query = nil
|
25
18
|
if loaded?
|
26
19
|
target.each { |r| r.raw_write_attribute(cache_column, timestamp) }
|
20
|
+
query = klass.where(klass.primary_key => target.map(&:id))
|
21
|
+
else
|
22
|
+
ids = [owner.send(using_reflection.association_primary_key), owner.send("#{using_reflection.association_primary_key}_was")].compact.uniq
|
23
|
+
arel_table = klass._reflections[using_reflection.inverse_of.options[:through].to_s].klass.arel_table
|
24
|
+
query = klass.joins(using_reflection.inverse_of.options[:through])
|
25
|
+
query = if using_reflection.is_a?(ActiveRecord::Reflection::HasAndBelongsToManyReflection)
|
26
|
+
query.where(arel_table[using_reflection.foreign_key].in(ids))
|
27
|
+
else
|
28
|
+
query.where(arel_table[using_reflection.inverse_of.foreign_key].in(ids))
|
29
|
+
end
|
27
30
|
end
|
28
|
-
|
31
|
+
|
29
32
|
query.update_all({ cache_column => timestamp })
|
30
33
|
traverse_relationships(klass, options[:cached_at], query, cache_column, timestamp)
|
31
34
|
end
|
32
35
|
|
33
|
-
def
|
34
|
-
return if owner.new_record? || records.empty?
|
35
|
-
|
36
|
+
def touch_records_cached_at(records, timestamp)
|
36
37
|
using_reflection = reflection.parent_reflection || reflection
|
37
|
-
|
38
|
+
|
38
39
|
if using_reflection.options[:cached_at]
|
39
|
-
|
40
40
|
if using_reflection.inverse_of.nil?
|
41
41
|
puts "WARNING: cannot updated cached at for relationship: #{klass.name}.#{name}, inverse_of not set"
|
42
42
|
return
|
43
43
|
end
|
44
44
|
|
45
45
|
cache_column = "#{using_reflection.inverse_of.name}_cached_at"
|
46
|
-
ids = records.inject([]) { |a, o| a += [o.send(klass.primary_key), o.send("#{klass.primary_key}_was")] }.compact.uniq
|
47
|
-
query = klass.where(klass.primary_key => ids)
|
48
46
|
records.each { |r| r.raw_write_attribute(cache_column, timestamp) }
|
47
|
+
query = klass.where(klass.primary_key => records.map(&:id))
|
49
48
|
query.update_all({ cache_column => timestamp })
|
50
49
|
traverse_relationships(klass, using_reflection.options[:cached_at], query, cache_column, timestamp)
|
51
50
|
end
|
52
|
-
|
51
|
+
|
53
52
|
if using_reflection.inverse_of&.options.try(:[], :cached_at) || using_reflection.inverse_of&.parent_reflection&.options.try(:[], :cached_at)
|
54
53
|
cache_column = "#{using_reflection.name}_cached_at"
|
55
54
|
owner.update_column(cache_column, timestamp) unless owner.new_record?
|
56
55
|
end
|
57
56
|
end
|
58
|
-
|
59
|
-
def touch_records_removed_cached_at(records, timestamp)
|
60
|
-
return if records.empty?
|
61
|
-
|
62
|
-
using_reflection = reflection.parent_reflection || reflection
|
63
|
-
inverse_reflection = using_reflection.inverse_of&.parent_reflection || using_reflection.inverse_of
|
64
|
-
|
65
|
-
if using_reflection.options[:cached_at]
|
66
|
-
if inverse_reflection.nil?
|
67
|
-
puts "WARNING: cannot updated cached at for relationship: #{klass.name}.#{name}, inverse_of not set"
|
68
|
-
return
|
69
|
-
end
|
70
|
-
|
71
|
-
cache_column = "#{inverse_reflection.name}_cached_at"
|
72
|
-
ids = records.inject([]) { |a, o| a += [o.send(klass.primary_key), o.send("#{klass.primary_key}_was")] }.compact.uniq
|
73
|
-
query = klass.where(klass.primary_key => ids)
|
74
|
-
records.each { |r| r.raw_write_attribute(cache_column, timestamp) }
|
75
|
-
query.update_all({ cache_column => timestamp })
|
76
|
-
traverse_relationships(klass, reflection.options[:cached_at], query, cache_column, timestamp)
|
77
|
-
end
|
78
|
-
|
79
|
-
if !inverse_reflection.nil? && inverse_reflection.options[:cached_at]
|
80
|
-
cache_column = "#{using_reflection.name}_cached_at"
|
81
|
-
owner.raw_write_attribute(cache_column, timestamp)
|
82
|
-
ids = records.inject([]) { |a, o| a += [o.send(klass.primary_key), o.send("#{klass.primary_key}_was")] }.compact.uniq
|
83
|
-
|
84
|
-
arel_table = if inverse_reflection.is_a?(ActiveRecord::Reflection::HasAndBelongsToManyReflection)
|
85
|
-
inverse_reflection.klass.const_get(:"HABTM_#{using_reflection.name.to_s.camelize}").arel_table
|
86
|
-
else
|
87
|
-
using_reflection.inverse_of.klass._reflections[using_reflection.inverse_of.options[:through].to_s].klass.arel_table
|
88
|
-
end
|
89
|
-
|
90
|
-
query = using_reflection.inverse_of.klass.where(using_reflection.inverse_of.klass.primary_key => owner.id)
|
91
|
-
query.update_all({ cache_column => timestamp })
|
92
|
-
puts "#{owner.class.name}.#{cache_column} = #{timestamp}"
|
93
|
-
owner.raw_write_attribute(cache_column, timestamp)
|
94
|
-
traverse_relationships(klass, reflection.options[:cached_at], query, cache_column, timestamp)
|
95
|
-
end
|
96
|
-
end
|
97
57
|
|
98
|
-
|
99
58
|
end
|
100
59
|
end
|
101
60
|
|
data/lib/cached_at/base.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require File.expand_path(File.join(__FILE__, '../association_extension'))
|
1
2
|
require File.expand_path(File.join(__FILE__, '../associations/association'))
|
2
3
|
require File.expand_path(File.join(__FILE__, '../associations/has_one_association'))
|
3
4
|
require File.expand_path(File.join(__FILE__, '../associations/belongs_to_association'))
|
@@ -8,23 +9,11 @@ module CachedAt
|
|
8
9
|
module Base
|
9
10
|
extend ActiveSupport::Concern
|
10
11
|
|
11
|
-
module AssociationExtension
|
12
|
-
|
13
|
-
def self.build(model, reflection)
|
14
|
-
return unless reflection.options[:cached_at]
|
15
|
-
end
|
16
|
-
|
17
|
-
def self.valid_options
|
18
|
-
[:cached_at]
|
19
|
-
end
|
20
|
-
|
21
|
-
end
|
22
|
-
|
23
12
|
included do
|
24
13
|
before_save :update_belongs_to_cached_at_keys
|
25
14
|
before_destroy { update_relations_cached_at(method: :destroy) }
|
26
|
-
after_touch { update_relations_cached_at_from_cached_at(method: :touch) }
|
27
15
|
|
16
|
+
after_touch { update_relations_cached_at_from_cached_at(method: :touch) }
|
28
17
|
after_save :update_relations_cached_at_from_cached_at
|
29
18
|
end
|
30
19
|
|
@@ -38,23 +27,45 @@ module CachedAt
|
|
38
27
|
end
|
39
28
|
|
40
29
|
def update_relations_cached_at(timestamp: nil, method: nil)
|
41
|
-
|
30
|
+
method = instance_variable_defined?(:@new_record_before_save) && @new_record_before_save ? :create : :update if method.nil?
|
31
|
+
|
32
|
+
return if method == :create && changes.empty?
|
33
|
+
return if method == :update && changes.empty?
|
34
|
+
|
42
35
|
timestamp ||= current_time_from_proper_timezone
|
43
36
|
|
44
37
|
self._reflections.each do |name, reflection|
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
38
|
+
|
39
|
+
through_connections = if reflection.polymorphic?
|
40
|
+
[]
|
41
|
+
else
|
42
|
+
reflection.klass._reflections.values.select do |r|
|
43
|
+
r.options[:cached_at] && r.options[:through] == reflection.inverse_of&.name
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
|
48
|
+
next unless reflection.options[:cached_at] || reflection&.parent_reflection&.class == ActiveRecord::Reflection::HasAndBelongsToManyReflection || !through_connections.empty?
|
49
|
+
next if instance_variable_defined?(:@relationships_cached_at_touched) && (!@relationships_cached_at_touched.nil? && @relationships_cached_at_touched[reflection.name])
|
50
|
+
next if reflection.is_a?(ActiveRecord::Reflection::HasManyReflection) && method == :create
|
51
|
+
|
52
|
+
assoc = association(name.to_sym)
|
53
|
+
assoc.touch_cached_at(timestamp, method)
|
54
|
+
|
55
|
+
through_connections.each do |r|
|
56
|
+
#TODO: move into association
|
57
|
+
cache_column = "#{r.inverse_of.name}_cached_at"
|
58
|
+
|
59
|
+
r.klass.where(r.association_primary_key => self.send(r.foreign_key)).update_all({
|
60
|
+
cache_column => timestamp
|
61
|
+
})
|
62
|
+
|
63
|
+
source_assoc = association(r.source_reflection_name.to_sym)
|
64
|
+
if source_assoc.loaded?
|
65
|
+
source_assoc.target.raw_write_attribute(cache_column, timestamp)
|
66
|
+
end
|
57
67
|
end
|
68
|
+
|
58
69
|
end
|
59
70
|
end
|
60
71
|
|
@@ -69,13 +80,12 @@ module CachedAt
|
|
69
80
|
elsif (self.changes[reflection.foreign_key] || self.new_record? || (self.association(reflection.name).loaded? && self.send(reflection.name) && self.send(reflection.name).id.nil?)) && self.send(reflection.name).try(:cached_at)
|
70
81
|
self.assign_attributes({ cache_column => self.send(reflection.name).cached_at })
|
71
82
|
end
|
72
|
-
|
73
83
|
end
|
84
|
+
|
74
85
|
end
|
75
86
|
end
|
76
87
|
|
77
88
|
end
|
78
89
|
end
|
79
90
|
|
80
|
-
ActiveRecord::Associations::Builder::Association.extensions << CachedAt::Base::AssociationExtension
|
81
91
|
ActiveRecord::Base.include(CachedAt::Base)
|
data/lib/cached_at/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: activerecord-cached_at
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jon Bracy
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-01-
|
11
|
+
date: 2017-01-09 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -135,6 +135,7 @@ files:
|
|
135
135
|
- ext/active_record/connection_adapters/abstract/schema_definitions.rb
|
136
136
|
- ext/active_record/connection_adapters/abstract/schema_statements.rb
|
137
137
|
- lib/cached_at.rb
|
138
|
+
- lib/cached_at/association_extension.rb
|
138
139
|
- lib/cached_at/associations/association.rb
|
139
140
|
- lib/cached_at/associations/belongs_to_association.rb
|
140
141
|
- lib/cached_at/associations/collection_association.rb
|