store_attribute 1.1.1 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/README.md +1 -1
- data/lib/store_attribute/active_record/store.rb +37 -14
- data/lib/store_attribute/active_record/type/typed_store.rb +10 -5
- data/lib/store_attribute/version.rb +1 -1
- metadata +11 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6c4bd7ca51c3191e560a7cfb18a9edde7caa40c571992a26a84352da9ee5d5d0
|
4
|
+
data.tar.gz: 2577ac2836e7c11b7857b5c8b98b8c3e208480b226e1ec2813ade8377324a97f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6f8bcb86379b5235cde3e19b96dbbba05ec2908b409882d872fb86913f2adfc9943f6a54bc0d20f5a8b5fd1c0373edc31594bc999d07c7f229954b13d5287567
|
7
|
+
data.tar.gz: cefb661c7a3e7f7add6a1ffac5eafcbae3941db2a4cc74a8e5fc5b827f10721c409ea8434730c8e6a0ba6cd706daa7e7b1276b7a52efe15bc6709e6047f6e055
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,24 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 1.3.0 (2024-09-03) 🗓️
|
6
|
+
|
7
|
+
- Fix using defaults when store attributes are inherited from a parent model. ([@palkan][])
|
8
|
+
|
9
|
+
- Allow specifying only default values w/o types. ([@palkan][])
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
store_attribute :store, :tags, default: []
|
13
|
+
```
|
14
|
+
|
15
|
+
- **Ruby >= 2.7 and Rails >= 6.1 are required**. ([@palkan][])
|
16
|
+
|
17
|
+
## 1.2.0 (2023-11-29)
|
18
|
+
|
19
|
+
- Support Rails >7.1. ([@palkan][])
|
20
|
+
|
21
|
+
- Fix handling of store attributes for not-yet-defined columns. ([@palkan][])
|
22
|
+
|
5
23
|
## 1.1.1 (2023-06-27)
|
6
24
|
|
7
25
|
- Lookup store attribute types only after schema load.
|
data/README.md
CHANGED
@@ -30,6 +30,7 @@ module ActiveRecord
|
|
30
30
|
# end
|
31
31
|
def store(store_name, options = {})
|
32
32
|
accessors = options.delete(:accessors)
|
33
|
+
accessor_related_options = options.slice(:prefix, :suffix)
|
33
34
|
typed_accessors =
|
34
35
|
if accessors && accessors.last.is_a?(Hash)
|
35
36
|
accessors.pop
|
@@ -38,7 +39,7 @@ module ActiveRecord
|
|
38
39
|
end
|
39
40
|
|
40
41
|
_orig_store_without_types(store_name, options)
|
41
|
-
store_accessor(store_name, *accessors, **typed_accessors) if accessors
|
42
|
+
store_accessor(store_name, *accessors, **accessor_related_options, **typed_accessors) if accessors
|
42
43
|
end
|
43
44
|
|
44
45
|
# Adds additional accessors to an existing store on this model.
|
@@ -114,17 +115,24 @@ module ActiveRecord
|
|
114
115
|
# u.ratio # => "3.141592653"
|
115
116
|
#
|
116
117
|
# # On the other hand, writing through accessor set correct data within store
|
117
|
-
# u.ratio = "3.
|
118
|
+
# u.ratio = "3.141592653"
|
118
119
|
# u.ratio # => 3
|
119
120
|
# u.settings['ratio'] # => 3
|
120
121
|
#
|
121
122
|
# For more examples on using types, see documentation for ActiveRecord::Attributes.
|
122
|
-
def store_attribute(store_name, name, type, prefix: nil, suffix: nil, **options)
|
123
|
+
def store_attribute(store_name, name, type = :value, prefix: nil, suffix: nil, **options)
|
123
124
|
_orig_store_accessor_without_types(store_name, name.to_s, prefix: prefix, suffix: suffix)
|
124
125
|
_define_predicate_method(name, prefix: prefix, suffix: suffix) if type == :boolean
|
125
126
|
|
126
|
-
_define_store_attribute(store_name) if !_local_typed_stored_attributes? ||
|
127
|
-
|
127
|
+
_define_store_attribute(store_name) if !_local_typed_stored_attributes? ||
|
128
|
+
_local_typed_stored_attributes[store_name][:types].empty? ||
|
129
|
+
# Defaults owner has changed, we must decorate the attribute to correctly propagate the defaults
|
130
|
+
(
|
131
|
+
options.key?(:default) && _local_typed_stored_attributes[store_name][:owner] != self
|
132
|
+
)
|
133
|
+
|
134
|
+
_local_typed_stored_attributes[store_name][:owner] = self if options.key?(:default) || !_local_typed_stored_attributes?
|
135
|
+
_local_typed_stored_attributes[store_name][:types][name] = [type, options]
|
128
136
|
end
|
129
137
|
|
130
138
|
def store_attribute_unset_values_fallback_to_default
|
@@ -148,27 +156,24 @@ module ActiveRecord
|
|
148
156
|
@local_typed_stored_attributes =
|
149
157
|
if superclass.respond_to?(:_local_typed_stored_attributes)
|
150
158
|
superclass._local_typed_stored_attributes.dup.tap do |h|
|
151
|
-
h.transform_values!
|
159
|
+
h.transform_values! { |v| {owner: v[:owner], types: v[:types].dup} }
|
152
160
|
end
|
153
161
|
else
|
154
|
-
Hash.new { |h, k| h[k] = {}.with_indifferent_access }.with_indifferent_access
|
162
|
+
Hash.new { |h, k| h[k] = {types: {}.with_indifferent_access} }.with_indifferent_access
|
155
163
|
end
|
156
164
|
end
|
157
165
|
|
158
166
|
def _define_store_attribute(store_name)
|
159
167
|
attr_name = store_name.to_s
|
160
|
-
was_type = attributes_to_define_after_schema_loads[attr_name]&.first
|
161
|
-
|
162
|
-
# For Rails <6.1
|
163
|
-
use_decorator = respond_to?(:decorate_attribute_type) && method(:decorate_attribute_type).parameters.count { |type, _| type == :req } == 2
|
164
168
|
|
165
169
|
defaultik = Type::TypedStore::Defaultik.new
|
166
170
|
|
167
171
|
owner = self
|
168
172
|
|
169
|
-
|
173
|
+
# For Rails <6.1
|
174
|
+
if respond_to?(:decorate_attribute_type) && method(:decorate_attribute_type).parameters.count { |type, _| type == :req } == 2
|
170
175
|
decorate_attribute_type(attr_name, "typed_accessor_for_#{attr_name}") do |subtype|
|
171
|
-
subtypes = _local_typed_stored_attributes[attr_name]
|
176
|
+
subtypes = _local_typed_stored_attributes[attr_name][:types]
|
172
177
|
type = Type::TypedStore.create_from_type(subtype)
|
173
178
|
type.owner = owner
|
174
179
|
defaultik.type = type
|
@@ -180,9 +185,27 @@ module ActiveRecord
|
|
180
185
|
|
181
186
|
type
|
182
187
|
end
|
188
|
+
# Rails >7.1
|
189
|
+
elsif respond_to?(:decorate_attributes)
|
190
|
+
decorate_attributes([attr_name]) do |_, subtype|
|
191
|
+
subtypes = _local_typed_stored_attributes[attr_name][:types]
|
192
|
+
type = Type::TypedStore.create_from_type(subtype)
|
193
|
+
type.owner = owner
|
194
|
+
defaultik.type = type
|
195
|
+
subtypes.each do |name, (cast_type, options)|
|
196
|
+
type.add_typed_key(name, cast_type, **options.symbolize_keys)
|
197
|
+
end
|
198
|
+
|
199
|
+
type
|
200
|
+
end
|
201
|
+
|
202
|
+
attribute(attr_name, default: defaultik.proc)
|
203
|
+
# Rails >=6.1, <=7.1
|
183
204
|
else
|
205
|
+
was_type = attributes_to_define_after_schema_loads[attr_name]&.first
|
206
|
+
|
184
207
|
attribute(attr_name, default: defaultik.proc) do |subtype|
|
185
|
-
subtypes = _local_typed_stored_attributes[attr_name]
|
208
|
+
subtypes = _local_typed_stored_attributes[attr_name][:types]
|
186
209
|
subtype = _lookup_cast_type(attr_name, was_type, {}) if defined?(_lookup_cast_type)
|
187
210
|
|
188
211
|
type = Type::TypedStore.create_from_type(subtype)
|
@@ -30,13 +30,14 @@ module ActiveRecord
|
|
30
30
|
def initialize(subtype)
|
31
31
|
@accessor_types = {}
|
32
32
|
@defaults = {}
|
33
|
-
@
|
34
|
-
super
|
33
|
+
@subtype = subtype
|
34
|
+
super
|
35
35
|
end
|
36
36
|
|
37
37
|
UNDEFINED = Object.new
|
38
38
|
|
39
39
|
def add_typed_key(key, type, default: UNDEFINED, **options)
|
40
|
+
type = ActiveModel::Type::Value.new(**options) if type == :value
|
40
41
|
type = ActiveRecord::Type.lookup(type, **options) if type.is_a?(Symbol)
|
41
42
|
safe_key = key.to_s
|
42
43
|
@accessor_types[safe_key] = type
|
@@ -61,7 +62,7 @@ module ActiveRecord
|
|
61
62
|
end
|
62
63
|
|
63
64
|
def serialize(value)
|
64
|
-
return super
|
65
|
+
return super unless value.is_a?(Hash)
|
65
66
|
typed_casted = {}
|
66
67
|
accessor_types.each do |str_key, type|
|
67
68
|
key = key_to_cast(value, str_key)
|
@@ -118,7 +119,7 @@ module ActiveRecord
|
|
118
119
|
def key_to_cast(val, key)
|
119
120
|
return key if val.key?(key)
|
120
121
|
return key.to_sym if val.key?(key.to_sym)
|
121
|
-
|
122
|
+
key if defaults.key?(key)
|
122
123
|
end
|
123
124
|
|
124
125
|
def typed?(key)
|
@@ -133,7 +134,11 @@ module ActiveRecord
|
|
133
134
|
owner&.store_attribute_unset_values_fallback_to_default && defaults.key?(key)
|
134
135
|
end
|
135
136
|
|
136
|
-
|
137
|
+
def store_accessor
|
138
|
+
subtype.accessor
|
139
|
+
end
|
140
|
+
|
141
|
+
attr_reader :accessor_types, :defaults, :subtype, :owner
|
137
142
|
end
|
138
143
|
end
|
139
144
|
end
|
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.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- palkan
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-09-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -16,28 +16,28 @@ dependencies:
|
|
16
16
|
requirements:
|
17
17
|
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '6.
|
19
|
+
version: '6.1'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '6.
|
26
|
+
version: '6.1'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: pg
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: '0
|
33
|
+
version: '1.0'
|
34
34
|
type: :development
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - ">="
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: '0
|
40
|
+
version: '1.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -91,7 +91,7 @@ metadata:
|
|
91
91
|
documentation_uri: http://github.com/palkan/store_attribute
|
92
92
|
homepage_uri: http://github.com/palkan/store_attribute
|
93
93
|
source_code_uri: http://github.com/palkan/store_attribute
|
94
|
-
post_install_message:
|
94
|
+
post_install_message:
|
95
95
|
rdoc_options: []
|
96
96
|
require_paths:
|
97
97
|
- lib
|
@@ -99,15 +99,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
99
99
|
requirements:
|
100
100
|
- - ">="
|
101
101
|
- !ruby/object:Gem::Version
|
102
|
-
version: 2.
|
102
|
+
version: 2.7.0
|
103
103
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
104
|
requirements:
|
105
105
|
- - ">="
|
106
106
|
- !ruby/object:Gem::Version
|
107
107
|
version: '0'
|
108
108
|
requirements: []
|
109
|
-
rubygems_version: 3.4.
|
110
|
-
signing_key:
|
109
|
+
rubygems_version: 3.4.19
|
110
|
+
signing_key:
|
111
111
|
specification_version: 4
|
112
112
|
summary: ActiveRecord extension which adds typecasting to store accessors
|
113
113
|
test_files: []
|