attr_json 0.6.0 → 0.7.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/Gemfile +1 -1
- data/README.md +16 -0
- data/gemfiles/rails_5_0.gemfile +1 -1
- data/gemfiles/rails_5_1.gemfile +1 -1
- data/gemfiles/rails_5_2.gemfile +1 -1
- data/gemfiles/rails_6_0.gemfile +1 -1
- data/gemfiles/rails_edge_6.gemfile +1 -1
- data/lib/attr_json/record.rb +45 -17
- data/lib/attr_json/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5fe1578a0dc062b2ca3c3b315da1e9c9e82b3a87a94e64db26f74a14e7b68335
|
4
|
+
data.tar.gz: f96ef69f875ba8652e7cb4c8366ff79a52eeeb7ad6531635ea2f3223dd6b3451
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c7f3df2f9f3072ec540a4dd4addeed8184c9f3da79fcf6c4d5939f5675729eee509e0362b1f603ef85fd1ea1606f1f6f8d79d1aeb5f90d073731d12281dfb473
|
7
|
+
data.tar.gz: 04b86f78256f0e53470aafe49168a2dcd019f45536485ad00f148998d5b4102981f25d35249e055561d137ee60a01e0a4a714792e00ac3bbb7d484dda27685d7
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -285,6 +285,20 @@ always mean 'contains' -- the previous query needs a `my_labels.hello`
|
|
285
285
|
which is a hash that includes the key/value, `lang: en`, it can have
|
286
286
|
other key/values in it too. String values will need to match exactly.
|
287
287
|
|
288
|
+
<a name="arbitrary-json-data"></a>
|
289
|
+
## Storing Arbitrary JSON data
|
290
|
+
|
291
|
+
Arbitrary JSON data (hashes, arrays, primitives of any depth) can be stored within attributes by using the rails built in `ActiveModel::Type::Value` as the attribute type. This is basically a "no-op" value type -- JSON alone will be used to serialize/deserialize whatever values you put there, because of the json type on the container field.
|
292
|
+
|
293
|
+
```ruby
|
294
|
+
class MyModel < ActiveRecord::Base
|
295
|
+
include AttrJson::Record
|
296
|
+
|
297
|
+
attr_json :arbitrary_hash, ActiveModel::Type::Value.new
|
298
|
+
end
|
299
|
+
|
300
|
+
```
|
301
|
+
|
288
302
|
|
289
303
|
<a name="forms"></a>
|
290
304
|
## Forms and Form Builders
|
@@ -450,3 +464,5 @@ There is a `./bin/console` that will give you a console in the context of attr_j
|
|
450
464
|
* Didn't actually notice existing [json_attributes](https://github.com/joel/json_attributes)
|
451
465
|
until I was well on my way here. I think it's not updated for Rails5 or type-aware,
|
452
466
|
haven't looked at it too much.
|
467
|
+
|
468
|
+
* [store_model](https://github.com/DmitryTsepelev/store_model) was created after `attr_json`, and has some overlapping functionality.
|
data/gemfiles/rails_5_0.gemfile
CHANGED
data/gemfiles/rails_5_1.gemfile
CHANGED
data/gemfiles/rails_5_2.gemfile
CHANGED
data/gemfiles/rails_6_0.gemfile
CHANGED
data/lib/attr_json/record.rb
CHANGED
@@ -26,6 +26,37 @@ module AttrJson
|
|
26
26
|
self.attr_json_registry = AttrJson::AttributeDefinition::Registry.new
|
27
27
|
end
|
28
28
|
|
29
|
+
protected
|
30
|
+
|
31
|
+
# adapted from ActiveRecord query_attribute method
|
32
|
+
# https://github.com/rails/rails/blob/v5.2.3/activerecord/lib/active_record/attribute_methods/query.rb#L12
|
33
|
+
#
|
34
|
+
# Sadly we could not re-use Rails code here, becuase the built-in method assumes attribute
|
35
|
+
# can be obtained with `self[attr_name]`, which you can not with attr_json (is that bad?), as
|
36
|
+
# well as `self.class.columns_hash[attr_name]` which you definitely can not (which is probably not bad),
|
37
|
+
# and has no way to use the value-translation semantics independently of that. May be a problem if
|
38
|
+
# ActiveRecord changes it's query method semantics in the future, will have to be sync'd here.
|
39
|
+
#
|
40
|
+
# Used to implement query methods on attr_json attributes, like `attr_json :foo, :string`, method `#foo?`
|
41
|
+
def self.attr_json_query_method(record, attribute)
|
42
|
+
value = record.send(attribute)
|
43
|
+
|
44
|
+
case value
|
45
|
+
when true
|
46
|
+
true
|
47
|
+
when false, nil, ActiveModel::Type::Boolean::FALSE_VALUES
|
48
|
+
false
|
49
|
+
else
|
50
|
+
if value.respond_to?(:to_i) && ( Numeric === value || value !~ /[^0-9]/ )
|
51
|
+
!value.to_i.zero?
|
52
|
+
elsif value.respond_to?(:zero?)
|
53
|
+
!value.zero?
|
54
|
+
else
|
55
|
+
!value.blank?
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
29
60
|
class_methods do
|
30
61
|
# Access or set class-wide json_attribute_config. Inherited by sub-classes,
|
31
62
|
# but setting on sub-classes is unique to subclass. Similar to how
|
@@ -133,30 +164,27 @@ module AttrJson
|
|
133
164
|
end
|
134
165
|
|
135
166
|
_attr_jsons_module.module_eval do
|
167
|
+
# For getter and setter, we used to use read_store_attribute/write_store_attribute
|
168
|
+
# copied from Rails store_accessor implementation.
|
169
|
+
# https://github.com/rails/rails/blob/74c3e43fba458b9b863d27f0c45fd2d8dc603cbc/activerecord/lib/active_record/store.rb#L90-L96
|
170
|
+
#
|
171
|
+
# But in fact just getting/setting in the hash provided to us by ActiveRecord json type
|
172
|
+
# container works BETTER for dirty tracking. We had a test that only passed doing it
|
173
|
+
# this simple way.
|
174
|
+
|
136
175
|
define_method("#{name}=") do |value|
|
137
176
|
attribute_def = self.class.attr_json_registry.fetch(name.to_sym)
|
138
|
-
|
139
|
-
# https://github.com/rails/rails/blob/74c3e43fba458b9b863d27f0c45fd2d8dc603cbc/activerecord/lib/active_record/store.rb#L90-L96
|
140
|
-
|
141
|
-
# special handling for nil, sorry, because if name key was previously
|
142
|
-
# not present, write_store_attribute by default will decide there was
|
143
|
-
# no change and refuse to make the change. TODO messy.
|
144
|
-
if value.nil? && !public_send(attribute_def.container_attribute).has_key?(attribute_def.store_key)
|
145
|
-
public_send :"#{attribute_def.container_attribute}_will_change!"
|
146
|
-
public_send(attribute_def.container_attribute)[attribute_def.store_key] = nil
|
147
|
-
else
|
148
|
-
# use of `write_store_attribute` is copied from Rails store_accessor implementation.
|
149
|
-
# https://github.com/rails/rails/blob/74c3e43fba458b9b863d27f0c45fd2d8dc603cbc/activerecord/lib/active_record/store.rb#L90-L96
|
150
|
-
write_store_attribute(attribute_def.container_attribute, attribute_def.store_key, attribute_def.cast(value))
|
151
|
-
end
|
177
|
+
public_send(attribute_def.container_attribute)[attribute_def.store_key] = attribute_def.cast(value)
|
152
178
|
end
|
153
179
|
|
154
180
|
define_method("#{name}") do
|
155
181
|
attribute_def = self.class.attr_json_registry.fetch(name.to_sym)
|
182
|
+
public_send(attribute_def.container_attribute)[attribute_def.store_key]
|
183
|
+
end
|
156
184
|
|
157
|
-
|
158
|
-
#
|
159
|
-
|
185
|
+
define_method("#{name}?") do
|
186
|
+
# implementation of `query_store_attribute` is based on Rails `query_attribute` implementation
|
187
|
+
AttrJson::Record.attr_json_query_method(self, name)
|
160
188
|
end
|
161
189
|
end
|
162
190
|
|
data/lib/attr_json/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: attr_json
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.7.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan Rochkind
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-04-16 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|