active_cached_resource 0.1.10 → 0.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 +7 -0
- data/lib/active_cached_resource/caching.rb +19 -9
- data/lib/active_cached_resource/caching_strategies/base.rb +1 -1
- data/lib/active_cached_resource/collection.rb +38 -6
- data/lib/active_cached_resource/version.rb +1 -1
- data/lib/activeresource/lib/active_resource/associations/builder/association.rb +1 -1
- data/lib/activeresource/lib/active_resource/associations.rb +9 -6
- data/lib/activeresource/lib/active_resource/base.rb +12 -0
- data/lib/activeresource/lib/active_resource/collection.rb +4 -4
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ff5568ae59b708a8797b4a76940222c5b6e6203ae6914fcefcccae0b6fd4702e
|
4
|
+
data.tar.gz: 810e8446382d26728299806a427f865de4fbda34de6704ceb3a231163b471c0a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c4e5b58ec0e1e9151c51e62e6760dd408098b68a01c634ca0ef62e2f999a6bb5c2d2a4961db0563a3d3a3490f9dcd6934c76a12e940233fd212a78fa6d34df4
|
7
|
+
data.tar.gz: b5d37c1863e51ef8aec7db5afebabe35a25d0aae60453a48ba61212f9348aea1dda4a1c43f0c00a5d80008d30170988bbf826eecc4e7fc74b7a5d978b63be67f
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## [0.2.0] - 2024-04-24
|
2
|
+
- Allow virtual attributes to be persisted into cache with introduction of `ActiveCachedResource::Collection.persisted_attribute`.
|
3
|
+
- Optimized cache key generation by switching from `SHA-256` to `MD5`, improving hashing performance while maintaining uniqueness.
|
4
|
+
|
5
|
+
## [0.1.10] - 2024-03-05
|
6
|
+
- Patch Collection#reload to return correct type
|
7
|
+
|
1
8
|
## [0.1.9] - 2024-02-05
|
2
9
|
- Fixed bug not allowing reloading collection cache
|
3
10
|
- Change debug to info for cache hits
|
@@ -40,9 +40,10 @@ module ActiveCachedResource
|
|
40
40
|
# @option options [Hash] :params
|
41
41
|
# Query and prefix (nested URL) parameters.
|
42
42
|
#
|
43
|
-
# @return [
|
43
|
+
# @return [ActiveCachedResource::Collection, ActiveCachedResource::Resource, nil]
|
44
|
+
# Returns the requested resource(s) based on the scope:
|
44
45
|
# * Returns a single resource object if `:one`, `:first`, `:last`, or an ID is given.
|
45
|
-
# * Returns an
|
46
|
+
# * Returns an ActiveCachedResource::Collection containing the resources if `:all` is given.
|
46
47
|
# * Returns `nil` if no data is found for `:one`, `:first`, `:last`, or `:all` queries.
|
47
48
|
#
|
48
49
|
# @raise [ResourceNotFound]
|
@@ -148,7 +149,7 @@ module ActiveCachedResource
|
|
148
149
|
#
|
149
150
|
# @return [void]
|
150
151
|
def clear_cache
|
151
|
-
cached_resource.logger.
|
152
|
+
cached_resource.logger.debug("Clearing cache for #{name} cache with prefix: #{cache_key_prefix}")
|
152
153
|
cached_resource.cache.clear(cache_key_prefix)
|
153
154
|
end
|
154
155
|
|
@@ -166,7 +167,7 @@ module ActiveCachedResource
|
|
166
167
|
|
167
168
|
return nil if json_string.nil?
|
168
169
|
|
169
|
-
cached_resource.logger.
|
170
|
+
cached_resource.logger.debug("[KEY:#{key}] Cache hit")
|
170
171
|
json_to_object(json_string)
|
171
172
|
end
|
172
173
|
|
@@ -242,11 +243,17 @@ module ActiveCachedResource
|
|
242
243
|
|
243
244
|
case resource
|
244
245
|
when Array
|
245
|
-
resource.map do |attrs|
|
246
|
+
elements = resource.map do |attrs|
|
246
247
|
new(attrs["object"], attrs["persistence"]).tap do |r|
|
247
248
|
r.prefix_options = object["prefix_options"]
|
248
249
|
end
|
249
250
|
end
|
251
|
+
object["collection_parser"].constantize.new(elements, object["from"]).tap do |parser|
|
252
|
+
parser.resource_class = self
|
253
|
+
parser.query_params = object["query_params"] || {}
|
254
|
+
parser.prefix_options = object["prefix_options"] || {}
|
255
|
+
parser.path_params = object["path_params"] || {}
|
256
|
+
end
|
250
257
|
else
|
251
258
|
new(resource["object"], resource["persistence"]).tap do |r|
|
252
259
|
r.prefix_options = object["prefix_options"]
|
@@ -258,13 +265,16 @@ module ActiveCachedResource
|
|
258
265
|
options = extract_options(*)
|
259
266
|
params = options.fetch(:params, {})
|
260
267
|
prefix_options, query_options = split_options(params)
|
261
|
-
json_object =
|
262
|
-
|
268
|
+
json_object = case object
|
269
|
+
when ActiveCachedResource::Collection
|
270
|
+
object.virtual_persistable_attributes.merge({
|
263
271
|
resource: object.map { |o| {object: o, persistence: o.persisted?} },
|
264
|
-
|
272
|
+
collection_parser: object.class.name,
|
273
|
+
from: object.from,
|
265
274
|
path_params: params,
|
275
|
+
prefix_options: prefix_options,
|
266
276
|
query_params: query_options
|
267
|
-
}
|
277
|
+
})
|
268
278
|
else
|
269
279
|
{
|
270
280
|
resource: {object: object, persistence: object.persisted?},
|
@@ -120,7 +120,7 @@ module ActiveCachedResource
|
|
120
120
|
if prefix.nil? || k.nil?
|
121
121
|
raise ArgumentError, "Key must have a prefix and a key separated by a dash"
|
122
122
|
end
|
123
|
-
"#{prefix}#{ActiveCachedResource::Constants::PREFIX_SEPARATOR}#{Digest::
|
123
|
+
"#{prefix}#{ActiveCachedResource::Constants::PREFIX_SEPARATOR}#{Digest::MD5.hexdigest(k)}"
|
124
124
|
end
|
125
125
|
|
126
126
|
def compress(value)
|
@@ -1,10 +1,27 @@
|
|
1
1
|
module ActiveCachedResource
|
2
2
|
class Collection < ActiveResource::Collection
|
3
|
-
|
3
|
+
class_attribute :virtual_persisted_attributes, default: []
|
4
|
+
|
5
|
+
# This method dynamically creates accessor methods for the specified attributes
|
6
|
+
# and adds them to a list of virtual persisted attributes to keep track of
|
7
|
+
# attributes that should be persisted to cache.
|
4
8
|
#
|
5
|
-
#
|
9
|
+
# @param args [Array<Symbol>] A list of attribute names to be persisted.
|
10
|
+
# @return [void]
|
11
|
+
def self.persisted_attribute(*args)
|
12
|
+
attr_accessor(*args)
|
13
|
+
self.virtual_persisted_attributes += args
|
14
|
+
end
|
15
|
+
|
16
|
+
def virtual_persistable_attributes
|
17
|
+
self.class.virtual_persisted_attributes.each_with_object({}) do |attribute, hash|
|
18
|
+
hash[attribute] = public_send(attribute)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Reload the collection by re-fetching the resources from the API.
|
6
23
|
#
|
7
|
-
# [Array<Object>] The collection of resources retrieved from the API.
|
24
|
+
# @return Returns [Array<Object>] The collection of resources retrieved from the API.
|
8
25
|
def reload
|
9
26
|
query_params[Constants::RELOAD_PARAM] = true
|
10
27
|
super
|
@@ -20,19 +37,34 @@ module ActiveCachedResource
|
|
20
37
|
should_reload = query_params.delete(Constants::RELOAD_PARAM)
|
21
38
|
if !should_reload
|
22
39
|
from_cache = resource_class.send(:cache_read, from, path_params, query_params, prefix_options)
|
23
|
-
|
24
|
-
|
40
|
+
if from_cache
|
41
|
+
update_self!(from_cache)
|
42
|
+
return @elements if @elements
|
43
|
+
end
|
25
44
|
end
|
26
45
|
|
27
46
|
super # This sets @elements
|
28
47
|
|
29
48
|
if resource_class.send(:should_cache?, @elements)
|
30
|
-
resource_class.send(:cache_write,
|
49
|
+
resource_class.send(:cache_write, self, from, path_params, query_params, prefix_options)
|
31
50
|
end
|
32
51
|
|
33
52
|
@elements
|
34
53
|
ensure
|
35
54
|
@requested = true
|
36
55
|
end
|
56
|
+
|
57
|
+
def update_self!(other_collection)
|
58
|
+
# Ensure that the virtual persisted attributes are also updated
|
59
|
+
self.class.virtual_persisted_attributes.each do |attribute|
|
60
|
+
public_send(:"#{attribute}=", other_collection.public_send(attribute))
|
61
|
+
end
|
62
|
+
|
63
|
+
@elements = other_collection.instance_variable_get(:@elements)
|
64
|
+
@from = other_collection.instance_variable_get(:@from)
|
65
|
+
@query_params = other_collection.query_params
|
66
|
+
@path_params = other_collection.path_params
|
67
|
+
@prefix_options = other_collection.prefix_options
|
68
|
+
end
|
37
69
|
end
|
38
70
|
end
|
@@ -4,7 +4,7 @@ module ActiveResource::Associations::Builder
|
|
4
4
|
class Association # :nodoc:
|
5
5
|
# providing a Class-Variable, which will have a different store of subclasses
|
6
6
|
class_attribute :valid_options
|
7
|
-
self.valid_options = [:class_name]
|
7
|
+
self.valid_options = [:class_name, :foreign_key]
|
8
8
|
|
9
9
|
# would identify subclasses of association
|
10
10
|
class_attribute :macro
|
@@ -1,11 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "pry-byebug" # IGNORE: This line is for debugging purposes and should be removed in production code.
|
3
4
|
module ActiveResource::Associations
|
4
5
|
module Builder
|
5
|
-
autoload :Association, "active_resource/associations/builder/association"
|
6
|
-
autoload :HasMany, "active_resource/associations/builder/has_many"
|
7
|
-
autoload :HasOne, "active_resource/associations/builder/has_one"
|
8
|
-
autoload :BelongsTo, "active_resource/associations/builder/belongs_to"
|
6
|
+
autoload :Association, "activeresource/lib/active_resource/associations/builder/association"
|
7
|
+
autoload :HasMany, "activeresource/lib/active_resource/associations/builder/has_many"
|
8
|
+
autoload :HasOne, "activeresource/lib/active_resource/associations/builder/has_one"
|
9
|
+
autoload :BelongsTo, "activeresource/lib/active_resource/associations/builder/belongs_to"
|
9
10
|
end
|
10
11
|
|
11
12
|
|
@@ -148,9 +149,11 @@ module ActiveResource::Associations
|
|
148
149
|
elsif attributes.include?(method_name)
|
149
150
|
attributes[method_name]
|
150
151
|
elsif !new_record?
|
151
|
-
|
152
|
+
# Association would be set on custom primary key if explicitly defined, otherwise use convention _id
|
153
|
+
assoc_key = self.class.custom_primary_key || "#{self.class.element_name}_id"
|
154
|
+
instance_variable_set(ivar_name, reflection.klass.find(:all, params: { assoc_key => self.id }))
|
152
155
|
else
|
153
|
-
instance_variable_set(ivar_name, reflection.klass.
|
156
|
+
instance_variable_set(ivar_name, reflection.klass.none)
|
154
157
|
end
|
155
158
|
end
|
156
159
|
end
|
@@ -672,6 +672,10 @@ module ActiveResource
|
|
672
672
|
end
|
673
673
|
end
|
674
674
|
|
675
|
+
def none
|
676
|
+
collection_parser.none
|
677
|
+
end
|
678
|
+
|
675
679
|
# An instance of ActiveResource::Connection that is the base \connection to the remote service.
|
676
680
|
# The +refresh+ parameter toggles whether or not the \connection is refreshed at every request
|
677
681
|
# or not (defaults to <tt>false</tt>).
|
@@ -717,6 +721,10 @@ module ActiveResource
|
|
717
721
|
|
718
722
|
attr_writer :primary_key
|
719
723
|
|
724
|
+
def custom_primary_key
|
725
|
+
@primary_key
|
726
|
+
end
|
727
|
+
|
720
728
|
def primary_key
|
721
729
|
if defined?(@primary_key)
|
722
730
|
@primary_key
|
@@ -1226,6 +1234,10 @@ module ActiveResource
|
|
1226
1234
|
load(attributes, false, persisted)
|
1227
1235
|
end
|
1228
1236
|
|
1237
|
+
def [](key)
|
1238
|
+
public_send(key)
|
1239
|
+
end
|
1240
|
+
|
1229
1241
|
# Returns a \clone of the resource that hasn't been assigned an +id+ yet and
|
1230
1242
|
# is treated as a \new resource.
|
1231
1243
|
#
|
@@ -6,12 +6,12 @@ require "active_support/inflector"
|
|
6
6
|
module ActiveResource # :nodoc:
|
7
7
|
class Collection # :nodoc:
|
8
8
|
include Enumerable
|
9
|
-
delegate :==, :[], :&, :*, :+, :-, :<=>, :all?, :any?, :as_json, :at, :assoc, :blank?, :bsearch, :bsearch_index,
|
10
|
-
:collect, :combination, :compact, :count, :cycle, :deconstruct, :deep_dup, :dig, :difference, :drop,
|
9
|
+
delegate :==, :[], :&, :*, :+, :-, :<=>, :<<, :all?, :any?, :as_json, :at, :assoc, :blank?, :bsearch, :bsearch_index,
|
10
|
+
:collect, :combination, :compact, :concat, :count, :cycle, :deconstruct, :deep_dup, :dig, :difference, :drop,
|
11
11
|
:drop_while, :each, :each_index, :empty?, :eql?, :excluding, :filter, :fifth, :find_index, :first,
|
12
|
-
:flatten, :
|
12
|
+
:flatten, :fourth, :hash, :include?, :including, :index, :inspect, :intersect?,
|
13
13
|
:intersection, :join, :last, :length, :map, :max, :min, :minmax, :none?, :one?, :pack, :permutation,
|
14
|
-
:pretty_print_cycle, :present?, :product, :reject, :repeated_combination, :repeated_permutation,
|
14
|
+
:pretty_print_cycle, :present?, :product, :push, :reject, :repeated_combination, :repeated_permutation,
|
15
15
|
:rassoc, :reverse, :reverse_each, :rindex, :rotate, :sample, :second, :second_to_last, :select,
|
16
16
|
:shelljoin, :shuffle, :size, :slice, :sort, :sum, :take, :take_while, :third, :third_to_last, :to,
|
17
17
|
:to_a, :to_ary, :to_fs, :to_formatted_s, :to_h, :to_param, :to_query, :to_s, :to_sentence, :to_xml,
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: active_cached_resource
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jean Luis Urena
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date:
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
11
11
|
dependencies:
|
12
12
|
- !ruby/object:Gem::Dependency
|
13
13
|
name: activemodel-serializers-xml
|
@@ -136,7 +136,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
136
|
- !ruby/object:Gem::Version
|
137
137
|
version: '0'
|
138
138
|
requirements: []
|
139
|
-
rubygems_version: 3.
|
139
|
+
rubygems_version: 3.7.0
|
140
140
|
specification_version: 4
|
141
141
|
summary: ActiveResource, but with a caching layer.
|
142
142
|
test_files: []
|