store_attribute 1.2.0 → 1.3.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 601846a5ef07068e0777b17cfb7896a6bcd1fe32ef93ac107f957c568a6598de
4
- data.tar.gz: 7ebee7679babde4188b07aa0504310001edbe31758070112b6f5c0e48eadc83d
3
+ metadata.gz: 6c4bd7ca51c3191e560a7cfb18a9edde7caa40c571992a26a84352da9ee5d5d0
4
+ data.tar.gz: 2577ac2836e7c11b7857b5c8b98b8c3e208480b226e1ec2813ade8377324a97f
5
5
  SHA512:
6
- metadata.gz: 64d0e3b562bd62b6e8b65b993f049b3af805d0a38f075218eaa05993f7229befbf10f21e59dd1709ddd1faa5397e20ca4f02c8800a703cee7f3db79b12a28a98
7
- data.tar.gz: 29623e721a38b1bf646f3a45c00c605c4162236716624e3cb8a0dceee69641d254145baa84b58008e3fe61084b1eb76249a34775f186bbe86861eca827ba2856
6
+ metadata.gz: 6f8bcb86379b5235cde3e19b96dbbba05ec2908b409882d872fb86913f2adfc9943f6a54bc0d20f5a8b5fd1c0373edc31594bc999d07c7f229954b13d5287567
7
+ data.tar.gz: cefb661c7a3e7f7add6a1ffac5eafcbae3941db2a4cc74a8e5fc5b827f10721c409ea8434730c8e6a0ba6cd706daa7e7b1276b7a52efe15bc6709e6047f6e055
data/CHANGELOG.md CHANGED
@@ -2,6 +2,18 @@
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
+
5
17
  ## 1.2.0 (2023-11-29)
6
18
 
7
19
  - 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)
@@ -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.0"
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.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: 2023-11-29 00:00:00.000000000 Z
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.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: []