store_attribute 1.2.0 → 1.3.1

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: 601846a5ef07068e0777b17cfb7896a6bcd1fe32ef93ac107f957c568a6598de
4
- data.tar.gz: 7ebee7679babde4188b07aa0504310001edbe31758070112b6f5c0e48eadc83d
3
+ metadata.gz: d79c58e23fa0838516c2eab7130ce8f121941bb99355d9ad7e24dbcb94f231be
4
+ data.tar.gz: 70cb3d8ff0a587f726756b2d2a1d89cd162fa49e286ee343c8311c9013a4a7f9
5
5
  SHA512:
6
- metadata.gz: 64d0e3b562bd62b6e8b65b993f049b3af805d0a38f075218eaa05993f7229befbf10f21e59dd1709ddd1faa5397e20ca4f02c8800a703cee7f3db79b12a28a98
7
- data.tar.gz: 29623e721a38b1bf646f3a45c00c605c4162236716624e3cb8a0dceee69641d254145baa84b58008e3fe61084b1eb76249a34775f186bbe86861eca827ba2856
6
+ metadata.gz: d15c7344b6f758cea9d405a3c5f765d4e9d6e734cae8866d44030c1788bf3c889ef6e3c2dae9bdb91976a45c7a0dbe3d4439f6cb5b81c169b97eefd1b264fc58
7
+ data.tar.gz: 8913905537ab1a151d6194b481ec46c17564515346dfe6d79cedb02281879b7e8b3ac906e7eb8dcacfcbab19d2cbe14a5d4097c2285d19827335c4420e0bf572
data/CHANGELOG.md CHANGED
@@ -2,6 +2,22 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 1.3.1 (2024-09-19)
6
+
7
+ - Populate missing defaults on user input when `store_attribute_unset_values_fallback_to_default` is true. ([@palkan][])
8
+
9
+ ## 1.3.0 (2024-09-03) 🗓️
10
+
11
+ - Fix using defaults when store attributes are inherited from a parent model. ([@palkan][])
12
+
13
+ - Allow specifying only default values w/o types. ([@palkan][])
14
+
15
+ ```ruby
16
+ store_attribute :store, :tags, default: []
17
+ ```
18
+
19
+ - **Ruby >= 2.7 and Rails >= 6.1 are required**. ([@palkan][])
20
+
5
21
  ## 1.2.0 (2023-11-29)
6
22
 
7
23
  - Support Rails >7.1. ([@palkan][])
data/README.md CHANGED
@@ -13,7 +13,7 @@ Originally extracted from not merged PR to Rails: [rails/rails#18942](https://gi
13
13
  In your Gemfile:
14
14
 
15
15
  ```ruby
16
- # for Rails 6+ (7 is supported)
16
+ # for Rails 6.1+ (7 is supported)
17
17
  gem "store_attribute", "~> 1.0"
18
18
 
19
19
  # for Rails 5+ (6 is supported)
@@ -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.14.1592653"
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? || _local_typed_stored_attributes[store_name].empty?
127
- _local_typed_stored_attributes[store_name][name] = [type, options]
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,10 +156,10 @@ 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!(&:dup)
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
 
@@ -165,7 +173,7 @@ module ActiveRecord
165
173
  # For Rails <6.1
166
174
  if respond_to?(:decorate_attribute_type) && method(:decorate_attribute_type).parameters.count { |type, _| type == :req } == 2
167
175
  decorate_attribute_type(attr_name, "typed_accessor_for_#{attr_name}") do |subtype|
168
- subtypes = _local_typed_stored_attributes[attr_name]
176
+ subtypes = _local_typed_stored_attributes[attr_name][:types]
169
177
  type = Type::TypedStore.create_from_type(subtype)
170
178
  type.owner = owner
171
179
  defaultik.type = type
@@ -180,7 +188,7 @@ module ActiveRecord
180
188
  # Rails >7.1
181
189
  elsif respond_to?(:decorate_attributes)
182
190
  decorate_attributes([attr_name]) do |_, subtype|
183
- subtypes = _local_typed_stored_attributes[attr_name]
191
+ subtypes = _local_typed_stored_attributes[attr_name][:types]
184
192
  type = Type::TypedStore.create_from_type(subtype)
185
193
  type.owner = owner
186
194
  defaultik.type = type
@@ -197,7 +205,7 @@ module ActiveRecord
197
205
  was_type = attributes_to_define_after_schema_loads[attr_name]&.first
198
206
 
199
207
  attribute(attr_name, default: defaultik.proc) do |subtype|
200
- subtypes = _local_typed_stored_attributes[attr_name]
208
+ subtypes = _local_typed_stored_attributes[attr_name][:types]
201
209
  subtype = _lookup_cast_type(attr_name, was_type, {}) if defined?(_lookup_cast_type)
202
210
 
203
211
  type = Type::TypedStore.create_from_type(subtype)
@@ -31,12 +31,13 @@ module ActiveRecord
31
31
  @accessor_types = {}
32
32
  @defaults = {}
33
33
  @subtype = subtype
34
- super(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(value) unless value.is_a?(Hash)
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)
@@ -79,6 +80,8 @@ module ActiveRecord
79
80
  accessor_types.each do |key, type|
80
81
  if hash.key?(key)
81
82
  hash[key] = type.cast(hash[key])
83
+ elsif fallback_to_default?(key)
84
+ hash[key] = built_defaults[key]
82
85
  end
83
86
  end
84
87
  hash
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module StoreAttribute # :nodoc:
4
- VERSION = "1.2.0"
4
+ VERSION = "1.3.1"
5
5
  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.2.0
4
+ version: 1.3.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - palkan
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2023-11-29 00:00:00.000000000 Z
11
+ date: 2024-09-19 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.0'
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.0'
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.18'
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.18'
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.6.0
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.20
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: []