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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: dda561b590231ab664acf2eb3cc4301d314cb046c137a4634e7ffbf69fcab023
4
- data.tar.gz: 3387445db5a9df2fe905bc58ad03bff68c6d3e8950a20d49df9abb1407e3f911
3
+ metadata.gz: 5fe1578a0dc062b2ca3c3b315da1e9c9e82b3a87a94e64db26f74a14e7b68335
4
+ data.tar.gz: f96ef69f875ba8652e7cb4c8366ff79a52eeeb7ad6531635ea2f3223dd6b3451
5
5
  SHA512:
6
- metadata.gz: 17f38aa4781d512e6082861b2fea83eff7c679be24ae78a1d86143399ca3185c535400521fe3dac9e4064f82cd4d0626bd9426af5bddafd6dbc6353a513959b9
7
- data.tar.gz: b8e05ea5e8cf5f9ec0c91ec4d2d3b6929f63325478b855a377abbcba0124a4c0450437c91b283a2257400d371c10a7781a8e49d3b319a7eb6c74218e9562a516
6
+ metadata.gz: c7f3df2f9f3072ec540a4dd4addeed8184c9f3da79fcf6c4d5939f5675729eee509e0362b1f603ef85fd1ea1606f1f6f8d79d1aeb5f90d073731d12281dfb473
7
+ data.tar.gz: 04b86f78256f0e53470aafe49168a2dcd019f45536485ad00f148998d5b4102981f25d35249e055561d137ee60a01e0a4a714792e00ac3bbb7d484dda27685d7
data/Gemfile CHANGED
@@ -30,7 +30,7 @@ gem 'cocoon', ">= 1.2"
30
30
  gem 'jquery-rails'
31
31
 
32
32
  gem 'capybara', "~> 3.0"
33
- gem "chromedriver-helper"
33
+ gem 'webdrivers', '~> 3.0'
34
34
  gem "selenium-webdriver"
35
35
 
36
36
  gem "byebug"
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.
@@ -11,7 +11,7 @@ gem "simple_form", ">= 4.0"
11
11
  gem "cocoon", ">= 1.2"
12
12
  gem "jquery-rails"
13
13
  gem "capybara", "~> 3.0"
14
- gem "chromedriver-helper"
14
+ gem "webdrivers", "~> 3.0"
15
15
  gem "selenium-webdriver"
16
16
  gem "byebug"
17
17
  gem "rails-ujs", require: false
@@ -11,7 +11,7 @@ gem "simple_form", ">= 4.0"
11
11
  gem "cocoon", ">= 1.2"
12
12
  gem "jquery-rails"
13
13
  gem "capybara", "~> 3.0"
14
- gem "chromedriver-helper"
14
+ gem "webdrivers", "~> 3.0"
15
15
  gem "selenium-webdriver"
16
16
  gem "byebug"
17
17
 
@@ -11,7 +11,7 @@ gem "simple_form", ">= 4.0"
11
11
  gem "cocoon", ">= 1.2"
12
12
  gem "jquery-rails"
13
13
  gem "capybara", "~> 3.0"
14
- gem "chromedriver-helper"
14
+ gem "webdrivers", "~> 3.0"
15
15
  gem "selenium-webdriver"
16
16
  gem "byebug"
17
17
 
@@ -11,7 +11,7 @@ gem "simple_form", ">= 4.0"
11
11
  gem "cocoon", ">= 1.2"
12
12
  gem "jquery-rails"
13
13
  gem "capybara", "~> 3.0"
14
- gem "chromedriver-helper"
14
+ gem "webdrivers", "~> 3.0"
15
15
  gem "selenium-webdriver"
16
16
  gem "byebug"
17
17
 
@@ -11,7 +11,7 @@ gem "simple_form", ">= 4.0"
11
11
  gem "cocoon", ">= 1.2"
12
12
  gem "jquery-rails"
13
13
  gem "capybara", "~> 3.0"
14
- gem "chromedriver-helper"
14
+ gem "webdrivers", "~> 3.0"
15
15
  gem "selenium-webdriver"
16
16
  gem "byebug"
17
17
  gem "coffee-rails"
@@ -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
- # write_store_attribute copied from Rails store_accessor implementation.
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
- # use of `read_store_attribute` is copied from Rails store_accessor implementation.
158
- # https://github.com/rails/rails/blob/74c3e43fba458b9b863d27f0c45fd2d8dc603cbc/activerecord/lib/active_record/store.rb#L90-L96
159
- read_store_attribute(attribute_def.container_attribute, attribute_def.store_key)
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
 
@@ -1,3 +1,3 @@
1
1
  module AttrJson
2
- VERSION = "0.6.0"
2
+ VERSION = "0.7.0"
3
3
  end
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.6.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-01-29 00:00:00.000000000 Z
11
+ date: 2019-04-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord