store_attribute 1.0.2 → 1.1.0
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 +20 -0
- data/LICENSE.txt +1 -1
- data/README.md +19 -6
- data/lib/store_attribute/active_record/store.rb +17 -0
- data/lib/store_attribute/active_record/type/typed_store.rb +13 -1
- data/lib/store_attribute/version.rb +1 -1
- data/lib/store_attribute.rb +3 -0
- 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: 2134f240621f2f546e5521fe4db4b66e3b6ec0a4a76ebb832fbcae8654c0904e
|
4
|
+
data.tar.gz: 862ce5201d0c1ad548035161b0f51b50a9a540a85ae8be0a9c550976f918701c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: efe4992702c419f392f4fcbfd16c0ab32c862acf4679e841a7a8c28d40e0fb2eb66c2b72b2ac0156517a49bce4ee7308ec75ffa64604d4b879c735da0201d7f3
|
7
|
+
data.tar.gz: a9b8d3683abcd37f99a7c0ef68431e80e32a79537c5dab426e150a85b7d15c4b8ce1cb92e0a6c1c24031418286223e854fb2e2c73083c801781553f6559cd2c1
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,26 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 1.1.0 (2023-03-08) 🌷
|
6
|
+
|
7
|
+
- Add configuration option to return default values when attribute key is not present in the serialized value ([@markedmondson][], [@palkan][]).
|
8
|
+
|
9
|
+
Add to the class (preferrable `ApplicationRecord` or some other base class):
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
class ApplicationRecord < ActiveRecord::Base
|
13
|
+
self.store_attribute_unset_values_fallback_to_default = true
|
14
|
+
|
15
|
+
store_attribute :extra, :color, :string, default: "grey"
|
16
|
+
end
|
17
|
+
|
18
|
+
user = User.create!(extra: {})
|
19
|
+
# without the fallback
|
20
|
+
user.color #=> nil
|
21
|
+
# with fallback
|
22
|
+
user.color #=> "grey"
|
23
|
+
```
|
24
|
+
|
5
25
|
## 1.0.2 (2022-07-29)
|
6
26
|
|
7
27
|
- Fix possible conflicts with Active Model objects. ([@palkan][])
|
data/LICENSE.txt
CHANGED
data/README.md
CHANGED
@@ -36,7 +36,7 @@ Where:
|
|
36
36
|
- `store_name` The name of the store.
|
37
37
|
- `name` The name of the accessor to the store.
|
38
38
|
- `type` A symbol such as `:string` or `:integer`, or a type object to be used for the accessor.
|
39
|
-
- `options` (optional) A hash of cast type options such as `precision`, `limit`, `scale`, `default`.
|
39
|
+
- `options` (optional) A hash of cast type options such as `precision`, `limit`, `scale`, `default`. Regular `store_accessor` options, such as `prefix`, `suffix` are also supported.
|
40
40
|
|
41
41
|
Type casting occurs every time you write data through accessor or update store itself
|
42
42
|
and when object is loaded from database.
|
@@ -131,17 +131,30 @@ end
|
|
131
131
|
Date.current #=> 2022-03-17
|
132
132
|
|
133
133
|
user = User.new
|
134
|
-
user.name #=> "
|
134
|
+
user.name #=> "Joe"
|
135
135
|
user.expired_at #=> 2022-03-19
|
136
136
|
user.save!
|
137
137
|
|
138
138
|
raw_user = RawUser.find(user.id)
|
139
|
-
|
140
|
-
|
139
|
+
raw_user.name #=> "Joe"
|
140
|
+
raw_user.expired_at #=> 2022-03-19
|
141
141
|
|
142
142
|
another_raw_user = RawUser.create!
|
143
143
|
another_user = User.find(another_raw_user.id)
|
144
144
|
|
145
|
-
|
146
|
-
|
145
|
+
another_user.name #=> nil
|
146
|
+
another_user.expired_at #=> nil
|
147
147
|
```
|
148
|
+
|
149
|
+
It is possible to configure `store_attribute` to return the default value even when the record is persisted and the attribute name is not present. By using the `store_attribute_unset_values_fallback_to_default` class option, default values will be returned for missing keys. For example:
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
class User < ApplicationRecord
|
153
|
+
self.store_attribute_unset_values_fallback_to_default = true
|
154
|
+
end
|
155
|
+
|
156
|
+
user = User.create!(extra: {})
|
157
|
+
user.expired_at #=> 2022-03-19
|
158
|
+
```
|
159
|
+
|
160
|
+
**IMPORTANT:** Due to implementation limitations, it's not recommended to toggle the value of `store_attribute_unset_values_fallback_to_default` in sub-classes. We recommend to set this value in base classes (e.g., `ApplicationRecord`).
|
@@ -10,6 +10,8 @@ module ActiveRecord
|
|
10
10
|
alias_method :_orig_store_without_types, :store
|
11
11
|
alias_method :_orig_store_accessor_without_types, :store_accessor
|
12
12
|
|
13
|
+
attr_writer :store_attribute_unset_values_fallback_to_default
|
14
|
+
|
13
15
|
# Defines store on this model.
|
14
16
|
#
|
15
17
|
# +store_name+ The name of the store.
|
@@ -125,6 +127,17 @@ module ActiveRecord
|
|
125
127
|
_store_local_stored_attribute(store_name, name, type, **options)
|
126
128
|
end
|
127
129
|
|
130
|
+
def store_attribute_unset_values_fallback_to_default
|
131
|
+
return @store_attribute_unset_values_fallback_to_default if instance_variable_defined?(:@store_attribute_unset_values_fallback_to_default)
|
132
|
+
|
133
|
+
@store_attribute_unset_values_fallback_to_default =
|
134
|
+
if superclass.respond_to?(:store_attribute_unset_values_fallback_to_default)
|
135
|
+
superclass.store_attribute_unset_values_fallback_to_default
|
136
|
+
else
|
137
|
+
false
|
138
|
+
end
|
139
|
+
end
|
140
|
+
|
128
141
|
def _store_local_stored_attribute(store_name, key, cast_type, default: Type::TypedStore::UNDEFINED, **options) # :nodoc:
|
129
142
|
cast_type = ActiveRecord::Type.lookup(cast_type, **options) if cast_type.is_a?(Symbol)
|
130
143
|
_local_typed_stored_attributes[store_name][key] = [cast_type, default]
|
@@ -156,10 +169,13 @@ module ActiveRecord
|
|
156
169
|
|
157
170
|
defaultik = Type::TypedStore::Defaultik.new
|
158
171
|
|
172
|
+
owner = self
|
173
|
+
|
159
174
|
if use_decorator
|
160
175
|
decorate_attribute_type(attr_name, "typed_accessor_for_#{attr_name}") do |subtype|
|
161
176
|
subtypes = _local_typed_stored_attributes[attr_name]
|
162
177
|
type = Type::TypedStore.create_from_type(subtype)
|
178
|
+
type.owner = owner
|
163
179
|
defaultik.type = type
|
164
180
|
subtypes.each { |name, (cast_type, default)| type.add_typed_key(name, cast_type, default: default) }
|
165
181
|
|
@@ -173,6 +189,7 @@ module ActiveRecord
|
|
173
189
|
subtype = _lookup_cast_type(attr_name, was_type, {}) if defined?(_lookup_cast_type)
|
174
190
|
|
175
191
|
type = Type::TypedStore.create_from_type(subtype)
|
192
|
+
type.owner = owner
|
176
193
|
defaultik.type = type
|
177
194
|
subtypes.each { |name, (cast_type, default)| type.add_typed_key(name, cast_type, default: default) }
|
178
195
|
|
@@ -25,6 +25,8 @@ module ActiveRecord
|
|
25
25
|
new(basetype)
|
26
26
|
end
|
27
27
|
|
28
|
+
attr_writer :owner
|
29
|
+
|
28
30
|
def initialize(subtype)
|
29
31
|
@accessor_types = {}
|
30
32
|
@defaults = {}
|
@@ -47,6 +49,8 @@ module ActiveRecord
|
|
47
49
|
accessor_types.each do |key, type|
|
48
50
|
if hash.key?(key)
|
49
51
|
hash[key] = type.deserialize(hash[key])
|
52
|
+
elsif fallback_to_default?(key)
|
53
|
+
hash[key] = built_defaults[key]
|
50
54
|
end
|
51
55
|
end
|
52
56
|
hash
|
@@ -106,6 +110,10 @@ module ActiveRecord
|
|
106
110
|
|
107
111
|
protected
|
108
112
|
|
113
|
+
def built_defaults
|
114
|
+
@built_defaults ||= build_defaults
|
115
|
+
end
|
116
|
+
|
109
117
|
# We cannot rely on string keys 'cause user input can contain symbol keys
|
110
118
|
def key_to_cast(val, key)
|
111
119
|
return key if val.key?(key)
|
@@ -121,7 +129,11 @@ module ActiveRecord
|
|
121
129
|
accessor_types.fetch(key.to_s)
|
122
130
|
end
|
123
131
|
|
124
|
-
|
132
|
+
def fallback_to_default?(key)
|
133
|
+
owner&.store_attribute_unset_values_fallback_to_default && defaults.key?(key)
|
134
|
+
end
|
135
|
+
|
136
|
+
attr_reader :accessor_types, :defaults, :store_accessor, :owner
|
125
137
|
end
|
126
138
|
end
|
127
139
|
end
|
data/lib/store_attribute.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: store_attribute
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0
|
4
|
+
version: 1.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- palkan
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2023-03-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -106,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
106
106
|
- !ruby/object:Gem::Version
|
107
107
|
version: '0'
|
108
108
|
requirements: []
|
109
|
-
rubygems_version: 3.
|
109
|
+
rubygems_version: 3.4.6
|
110
110
|
signing_key:
|
111
111
|
specification_version: 4
|
112
112
|
summary: ActiveRecord extension which adds typecasting to store accessors
|