activemodel-caching 0.1.0 → 0.1.2

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: 3e5807404927b4493c98793dc6c099499ab0c4debe20508b48f9f901ccb0c6b7
4
- data.tar.gz: aba1ed74fe1f01fa24fe90d6783422ca13a3f4b1b94d20efc9374a187afed52b
3
+ metadata.gz: 8b303bf8dad12f99a476fd5848f7c86a2955529bf3525685885d18bdcb8c6910
4
+ data.tar.gz: 475519f8c787511aa0c4511b066430cf77a894c3d3bdfce89abf6c7c8fd8f57b
5
5
  SHA512:
6
- metadata.gz: f741d748d3f3580af8524554da1f1146d7762f406bba7279332c36fd097cb5d4f40213a54ab8c097e5c281187d54272600f1eab5d45d855a864177be488083d0
7
- data.tar.gz: 5ebfb56ecb0debd6b2afa33ced087e7eefbd36bef5ba39705c32ad8eceff9fcc29fdeefa2c22af0eb0039351b55aac727a402dccf6a9fd565bb2bf845b81bb4c
6
+ metadata.gz: 418a295855396e610ed66f8bcb72f531131b533d5e5efbebe70e0cfcec46acdf56a38a3f1940a7d69f66f0e425d1ef80d61b99f51f95c34aea072885b5774cb1
7
+ data.tar.gz: d010322be580cca50eebf1558196c8b3f129a5140bb57a47b2afeb8b3aa3fb4a5c44cd91cbc38c2e4ab8cc6d93d60d0677cd3145c22a59be38b18523632adfb0
data/.rubocop.yml CHANGED
@@ -1,4 +1,6 @@
1
1
  AllCops:
2
+ NewCops: enable
3
+ SuggestExtensions: false
2
4
  TargetRubyVersion: 3.0
3
5
 
4
6
  Metrics/BlockLength:
data/CHANGELOG.md CHANGED
@@ -1,5 +1,9 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.1.1] - 2024-11-13
4
+
5
+ - Minor bug fixes
6
+
3
7
  ## [0.1.0] - 2024-11-13
4
8
 
5
9
  - Initial release
data/README.md CHANGED
@@ -10,65 +10,26 @@ Add this line to your application's Gemfile:
10
10
  gem 'activemodel-caching'
11
11
  ```
12
12
 
13
- And then execute:
13
+ Then execute:
14
14
 
15
15
  ```bash
16
- bundle install
16
+ $ bundle install
17
17
  ```
18
18
 
19
- Or install it yourself as:
19
+ ## Configuration
20
20
 
21
- ```bash
22
- gem install activemodel-caching
23
- ```
24
-
25
- ## Usage
26
-
27
- To use the caching methods provided by `ActiveModel::Caching`, include the module in your model and set up the cache store.
28
-
29
- ### Setup
30
-
31
- You can set up a cache store globally in an initializer, for example, in `config/initializers/active_model_caching.rb`:
21
+ Configure the gem in an initializer:
32
22
 
33
23
  ```ruby
34
24
  ActiveModel::Caching.setup do |config|
35
- config.cache_store = ActiveSupport::Cache::MemoryStore.new # or any other cache store you prefer
25
+ config.cache_store = Rails.cache # Defaults to Rails.cache if Rails is defined, otherwise to memory store
26
+ config.global_id_app = 'MyApp' # Defaults to GlobalID.app if present, otherwise to Rails.application.name if Rails is defined
36
27
  end
37
28
  ```
38
29
 
39
- If you're using Rails, you can also default to Rails cache if you prefer:
40
- ```ruby
41
- ActiveModel::Caching.setup do |config|
42
- config.cache_store = Rails.cache
43
- end
44
- ```
45
-
46
- ### Basic Usage
47
-
48
- To enable caching for an attribute, simply call one of the `cache_*` methods in your model class. Here are the methods you can use:
49
-
50
- - `cache_string` - Caches a string value.
51
- - `cache_integer` - Caches an integer value.
52
- - `cache_decimal` - Caches a decimal value.
53
- - `cache_datetime` - Caches a datetime value.
54
- - `cache_flag` - Caches a boolean flag.
55
- - `cache_float` - Caches a float value.
56
- - `cache_enum` - Caches an enumerated value.
57
- - `cache_json` - Caches a JSON object.
58
- - `cache_list` - Caches an ordered list with an optional limit.
59
- - `cache_unique_list` - Caches a unique list with an optional limit.
60
- - `cache_set` - Caches a unique set with an optional limit.
61
- - `cache_ordered_set` - Caches an ordered set with an optional limit.
62
- - `cache_slots` - Caches available "slots" (e.g., seats) with helper methods.
63
- - `cache_slot` - Caches a single-slot availability.
64
- - `cache_counter` - Caches a counter that can be incremented and reset.
65
- - `cache_limiter` - Caches a limited counter, enforcing a maximum count.
66
- - `cache_hash` - Caches a hash structure.
67
- - `cache_boolean` - Caches a boolean value.
68
-
69
- #### Example
30
+ ## Usage
70
31
 
71
- Here’s how you might define a model with various cached attributes:
32
+ Include the module in your class:
72
33
 
73
34
  ```ruby
74
35
  class User
@@ -76,87 +37,202 @@ class User
76
37
 
77
38
  cache_string :session_token
78
39
  cache_integer :view_count
79
- cache_decimal :account_balance
80
- cache_datetime :last_login
81
- cache_flag :is_active
82
- cache_enum :status, %w[active inactive suspended]
83
- cache_json :preferences
84
- cache_list :recent_searches, limit: 10
85
- cache_set :tags, limit: 5
86
- cache_slots :seats, available: 100
87
- cache_counter :login_count
88
- cache_boolean :is_verified
40
+ # ... etc
89
41
  end
90
42
  ```
91
43
 
92
- With these, you’ll automatically have generated methods for interacting with the cache.
44
+ ## Available Cache Types
45
+
46
+ ### Basic Types
47
+
48
+ #### `cache_string`
49
+ Caches a string value.
50
+ ```ruby
51
+ cache_string :session_token
52
+ # Generates:
53
+ # - session_token
54
+ # - session_token=
55
+ ```
56
+
57
+ #### `cache_integer`
58
+ Caches an integer value.
59
+ ```ruby
60
+ cache_integer :view_count
61
+ # Generates:
62
+ # - view_count
63
+ # - view_count=
64
+ ```
93
65
 
94
- ### Detailed Method Descriptions
66
+ #### `cache_decimal`
67
+ Caches a decimal value.
68
+ ```ruby
69
+ cache_decimal :account_balance
70
+ # Generates:
71
+ # - account_balance
72
+ # - account_balance=
73
+ ```
74
+
75
+ #### `cache_datetime`
76
+ Caches a datetime value.
77
+ ```ruby
78
+ cache_datetime :last_login
79
+ # Generates:
80
+ # - last_login
81
+ # - last_login=
82
+ ```
95
83
 
96
- - **`cache_string(attribute_name, expires_in: nil)`**: Caches a string attribute.
97
- - Example: `cache_string :username`
84
+ #### `cache_flag` / `cache_boolean`
85
+ Caches a boolean value.
86
+ ```ruby
87
+ cache_flag :is_active
88
+ # or
89
+ cache_boolean :is_verified
90
+ # Generates:
91
+ # - is_active
92
+ # - is_active=
93
+ ```
98
94
 
99
- - **`cache_integer(attribute_name, expires_in: nil)`**: Caches an integer attribute.
100
- - Example: `cache_integer :view_count`
95
+ #### `cache_float`
96
+ Caches a float value.
97
+ ```ruby
98
+ cache_float :average_rating
99
+ # Generates:
100
+ # - average_rating
101
+ # - average_rating=
102
+ ```
101
103
 
102
- - **`cache_decimal(attribute_name, expires_in: nil)`**: Caches a decimal attribute.
103
- - Example: `cache_decimal :account_balance`
104
+ ### Complex Types
104
105
 
105
- - **`cache_datetime(attribute_name, expires_in: nil)`**: Caches a datetime attribute.
106
- - Example: `cache_datetime :last_login`
106
+ #### `cache_enum`
107
+ Caches an enum value, storing the value among defined options.
108
+ ```ruby
109
+ cache_enum :status, %w[active inactive suspended]
110
+ # Generates:
111
+ # - status
112
+ # - status=
113
+ ```
107
114
 
108
- - **`cache_flag(attribute_name, expires_in: nil)`**: Caches a boolean flag.
109
- - Example: `cache_flag :is_active`
115
+ #### `cache_json`
116
+ Caches a JSON value.
117
+ ```ruby
118
+ cache_json :user_preferences
119
+ # Generates:
120
+ # - user_preferences
121
+ # - user_preferences=
122
+ ```
110
123
 
111
- - **`cache_enum(attribute_name, options, expires_in: nil)`**: Caches an enumerated value.
112
- - Example: `cache_enum :status, %w[active inactive suspended]`
124
+ #### `cache_hash`
125
+ Caches a hash value.
126
+ ```ruby
127
+ cache_hash :settings
128
+ # Generates:
129
+ # - settings
130
+ # - settings=
131
+ ```
113
132
 
114
- - **`cache_json(attribute_name, expires_in: nil)`**: Caches a JSON object.
115
- - Example: `cache_json :user_preferences`
133
+ ### Collections
116
134
 
117
- - **`cache_list(attribute_name, limit: nil, expires_in: nil)`**: Caches an ordered list, with an optional limit.
118
- - Example: `cache_list :recent_posts, limit: 5`
135
+ #### `cache_list`
136
+ Caches an ordered list of values, maintaining order and optional limit.
137
+ ```ruby
138
+ cache_list :recent_posts, limit: 5
139
+ # Generates:
140
+ # - recent_posts
141
+ # - add_to_recent_posts
142
+ # - remove_from_recent_posts
143
+ ```
119
144
 
120
- - **`cache_set(attribute_name, limit: nil, expires_in: nil)`**: Caches a unique set, with an optional limit.
121
- - Example: `cache_set :tags, limit: 10`
145
+ #### `cache_unique_list`
146
+ Caches a unique list of values, maintaining uniqueness and optional limit.
147
+ ```ruby
148
+ cache_unique_list :favorite_articles, limit: 10
149
+ # Generates:
150
+ # - favorite_articles
151
+ # - add_to_favorite_articles
152
+ # - remove_from_favorite_articles
153
+ ```
122
154
 
123
- - **`cache_slots(attribute_name, available:, expires_in: nil)`**: Caches a set number of slots with helper methods.
124
- - Example: `cache_slots :seats, available: 100`
155
+ #### `cache_set`
156
+ Caches a set of unique values with optional limit.
157
+ ```ruby
158
+ cache_set :tags, limit: 5
159
+ # Generates:
160
+ # - tags
161
+ # - add_to_tags
162
+ # - remove_from_tags
163
+ ```
125
164
 
126
- - **`cache_counter(attribute_name, expires_in: nil)`**: Caches a counter.
127
- - Example: `cache_counter :login_count`
165
+ #### `cache_ordered_set`
166
+ Caches an ordered set of values, maintaining order and optional limit.
167
+ ```ruby
168
+ cache_ordered_set :recent_views, limit: 10
169
+ # Generates:
170
+ # - recent_views
171
+ # - add_to_recent_views
172
+ # - remove_from_recent_views
173
+ ```
128
174
 
129
- - **`cache_boolean(attribute_name, expires_in: nil)`**: Caches a boolean value.
130
- - Example: `cache_boolean :is_verified`
175
+ ### Special Types
131
176
 
132
- ### Example Methods
177
+ #### `cache_slots`
178
+ Caches a limited number of available "slots" for resources like seats or reservations.
179
+ ```ruby
180
+ cache_slots :seats, available: 10
181
+ # Generates:
182
+ # - seats
183
+ # - available_seats?
184
+ # - reserve_seats!
185
+ # - release_seats!
186
+ # - reset_seats!
187
+ ```
133
188
 
134
- For each cached attribute, methods are generated for getting and setting values. For example:
189
+ #### `cache_slot`
190
+ Caches a single slot (binary available/taken resource).
191
+ ```ruby
192
+ cache_slot :parking_space
193
+ # Generates:
194
+ # - parking_space
195
+ # - available_parking_space?
196
+ # - reserve_parking_space!
197
+ # - release_parking_space!
198
+ # - reset_parking_space!
199
+ ```
135
200
 
201
+ #### `cache_counter`
202
+ Caches a counter value.
136
203
  ```ruby
137
- user = User.new
204
+ cache_counter :likes_count
205
+ # Generates:
206
+ # - likes_count
207
+ # - increment_likes_count
208
+ # - decrement_likes_count
209
+ # - reset_likes_count
210
+ ```
138
211
 
139
- # Cache a string
140
- user.session_token = "abc123"
141
- puts user.session_token # => "abc123"
212
+ #### `cache_limiter`
213
+ Caches a limiter value with a maximum allowed count.
214
+ ```ruby
215
+ cache_limiter :api_requests, limit: 100
216
+ # Generates:
217
+ # - api_requests
218
+ # - increment_api_requests
219
+ # - reset_api_requests
220
+ ```
142
221
 
143
- # Increment a counter
144
- user.increment_login_count
145
- puts user.login_count # => 1
222
+ ## Options
146
223
 
147
- # Reserve a slot
148
- if user.available_seats?
149
- user.reserve_seats!
150
- end
224
+ All cache methods accept an optional `expires_in` parameter:
151
225
 
152
- # Reset a slot
153
- user.reset_seats!
226
+ ```ruby
227
+ cache_string :session_token, expires_in: 1.hour
228
+ cache_counter :daily_visits, expires_in: 1.day
154
229
  ```
155
230
 
156
231
  ## Contributing
157
232
 
158
- Bug reports and pull requests are welcome on GitHub at [https://github.com/your-username/active_model-caching](https://github.com/your-username/active_model-caching).
233
+ Bug reports and pull requests are welcome at https://github.com/EmCousin/activemodel-caching.
159
234
 
160
235
  ## License
161
236
 
162
- The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
237
+ This gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
238
+ ```
@@ -2,6 +2,6 @@
2
2
 
3
3
  module ActiveModel
4
4
  module Caching
5
- VERSION = "0.1.0"
5
+ VERSION = "0.1.2"
6
6
  end
7
7
  end
@@ -2,25 +2,81 @@
2
2
 
3
3
  require_relative "caching/version"
4
4
 
5
+ require "active_support"
6
+ require "active_support/time"
5
7
  require "base64"
6
8
  require "bigdecimal/util"
9
+ require "global_id"
7
10
  require "json"
8
- require "active_support"
9
- require "active_support/time"
10
11
 
11
12
  module ActiveModel
12
13
  # Provides with a set of methods allowing to cache data structures at the object level
13
14
  module Caching
14
- mattr_accessor :cache_store
15
- @@cache_store = ActiveSupport::Cache::MemoryStore.new
15
+ extend ActiveSupport::Concern
16
+
17
+ include GlobalID::Identification
16
18
 
17
19
  class << self
20
+ # Configures the gem with a block. Example:
21
+ # ActiveModel::Caching.setup do |config|
22
+ # config.cache_store = Rails.cache
23
+ # config.global_id_app = 'MyApp'
24
+ # end
25
+ #
26
+ # @yield [ActiveModel::Caching] Yields self for configuration
27
+ # @return [void]
18
28
  def setup
19
29
  yield self
20
30
  end
31
+
32
+ # Returns the cache store to use for caching attributes.
33
+ # Defaults to Rails.cache if Rails is defined, otherwise uses MemoryStore.
34
+ #
35
+ # @return [ActiveSupport::Cache::Store] The configured cache store
36
+ def cache_store
37
+ @cache_store ||= default_cache_store
38
+ end
39
+
40
+ # Returns the application name used for GlobalID generation.
41
+ # Defaults to GlobalID.app if present, then Rails.application.name if Rails is defined.
42
+ #
43
+ # @return [String, nil] The configured application name for GlobalID
44
+ def global_id_app
45
+ @global_id_app ||= default_global_id_app
46
+ end
47
+
48
+ attr_writer :cache_store, :global_id_app
49
+
50
+ private
51
+
52
+ # @private
53
+ # Returns the default cache store based on the environment.
54
+ #
55
+ # @return [ActiveSupport::Cache::Store] The default cache store
56
+ def default_cache_store
57
+ if defined?(Rails)
58
+ Rails.cache
59
+ else
60
+ ActiveSupport::Cache::MemoryStore.new
61
+ end
62
+ end
63
+
64
+ # @private
65
+ # Returns the default application name for GlobalID based on the environment.
66
+ #
67
+ # @return [String, nil] The default application name
68
+ def default_global_id_app
69
+ if GlobalID.app.present?
70
+ GlobalID.app
71
+ elsif defined?(Rails)
72
+ Rails.application.name
73
+ end
74
+ end
21
75
  end
22
76
 
23
- extend ActiveSupport::Concern
77
+ included do
78
+ delegate :cache_store, to: ActiveModel::Caching
79
+ end
24
80
 
25
81
  class_methods do
26
82
  # Caches a string value for the given attribute.
@@ -117,6 +173,7 @@ module ActiveModel
117
173
 
118
174
  attribute_name
119
175
  end
176
+ alias_method :cache_boolean, :cache_flag
120
177
 
121
178
  # Caches a float value for the given attribute.
122
179
  #
@@ -426,6 +483,11 @@ module ActiveModel
426
483
  cache_store.write(cache_key_for(attribute_name), new_value, expires_in: expires_in)
427
484
  end
428
485
 
486
+ define_method(:"decrement_#{attribute_name}") do
487
+ new_value = send(attribute_name) - 1
488
+ cache_store.write(cache_key_for(attribute_name), new_value, expires_in: expires_in)
489
+ end
490
+
429
491
  define_method(:"reset_#{attribute_name}") do
430
492
  cache_store.write(cache_key_for(attribute_name), 0, expires_in: expires_in)
431
493
  end
@@ -483,23 +545,6 @@ module ActiveModel
483
545
 
484
546
  attribute_name
485
547
  end
486
-
487
- # Caches a boolean value for the given attribute.
488
- #
489
- # @param attribute_name [Symbol] the name of the boolean attribute to cache.
490
- # @param expires_in [ActiveSupport::Duration, nil] optional expiration time for the cache entry.
491
- #
492
- # @example
493
- # cache_boolean :is_verified
494
- def cache_boolean(attribute_name, expires_in: nil)
495
- define_method(attribute_name) do
496
- cache_store.read(cache_key_for(attribute_name)).present?
497
- end
498
-
499
- define_method(:"#{attribute_name}=") do |value|
500
- cache_store.write(cache_key_for(attribute_name), !!value, expires_in: expires_in)
501
- end
502
- end
503
548
  end
504
549
 
505
550
  private
@@ -509,7 +554,11 @@ module ActiveModel
509
554
  # @param attribute_name [Symbol] the name of the attribute.
510
555
  # @return [String] the generated cache key.
511
556
  def cache_key_for(attribute_name)
512
- to_global_id(attribute_name: attribute_name)
557
+ if ActiveModel::Caching.global_id_app.present?
558
+ to_global_id(attribute_name: attribute_name, app: ActiveModel::Caching.global_id_app)
559
+ else
560
+ to_global_id(attribute_name: attribute_name)
561
+ end
513
562
  end
514
563
  end
515
564
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activemodel-caching
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Emmanuel Cousin
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-11-13 00:00:00.000000000 Z
11
+ date: 2024-11-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -53,33 +53,33 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: 3.1.2
55
55
  - !ruby/object:Gem::Dependency
56
- name: json
56
+ name: globalid
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
60
60
  - !ruby/object:Gem::Version
61
- version: '2.8'
61
+ version: '1.2'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: '2.8'
68
+ version: '1.2'
69
69
  - !ruby/object:Gem::Dependency
70
- name: globalid
70
+ name: json
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
74
74
  - !ruby/object:Gem::Version
75
- version: '1.2'
75
+ version: '2.8'
76
76
  type: :runtime
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.2'
82
+ version: '2.8'
83
83
  description: ActiveModel::Caching is a versatile gem for managing structured, temporary
84
84
  data using a caching backend, typically Rails cache for Rails applications. This
85
85
  gem provides an easy-to-use API for storing, retrieving, and manipulating data structures
@@ -105,6 +105,7 @@ licenses:
105
105
  - MIT
106
106
  metadata:
107
107
  allowed_push_host: https://rubygems.org
108
+ rubygems_mfa_required: 'true'
108
109
  homepage_uri: https://github.com/EmCousin/activemodel-caching
109
110
  source_code_uri: https://github.com/EmCousin/activemodel-caching
110
111
  post_install_message: