deco_lite 0.3.2 → 0.3.3
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.lock +3 -3
- data/README.md +44 -17
- data/lib/deco_lite/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: 77c440561731ca11332b76f0ee373e4568d4e84c11930d530d1dde9d5c097eb9
|
4
|
+
data.tar.gz: f771f70f192ae1c2b2d7a935933f7157cde64c6f44e9dc60d50e66d58e8abb05
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6aa192d5c0d1c68860a4e41c31c3997307e90560d293ba6d2e1f5d30a82f537358988cfba766f34415c8321041f3844c2ac88d176a818647f13474f86171c3f6
|
7
|
+
data.tar.gz: e7910463ad7ede8f002af8bc0f46c220bcb715dce09d1690c10b3a3af7db66577acd372a607698470b2fd168a8295d3b24c1fd705601064f02e2f54e0f5ef350
|
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
deco_lite (0.3.
|
4
|
+
deco_lite (0.3.3)
|
5
5
|
activemodel (~> 7.0, >= 7.0.3.1)
|
6
6
|
activesupport (~> 7.0, >= 7.0.3.1)
|
7
7
|
immutable_struct_ex (~> 0.2.0)
|
@@ -25,7 +25,7 @@ GEM
|
|
25
25
|
docile (1.4.0)
|
26
26
|
i18n (1.12.0)
|
27
27
|
concurrent-ruby (~> 1.0)
|
28
|
-
immutable_struct_ex (0.2.
|
28
|
+
immutable_struct_ex (0.2.3)
|
29
29
|
json (2.6.2)
|
30
30
|
kwalify (0.7.2)
|
31
31
|
mad_flatter (1.0.1.pre.beta)
|
@@ -63,7 +63,7 @@ GEM
|
|
63
63
|
diff-lcs (>= 1.2.0, < 2.0)
|
64
64
|
rspec-support (~> 3.11.0)
|
65
65
|
rspec-support (3.11.0)
|
66
|
-
rubocop (1.35.
|
66
|
+
rubocop (1.35.1)
|
67
67
|
json (~> 2.3)
|
68
68
|
parallel (~> 1.10)
|
69
69
|
parser (>= 3.1.2.1)
|
data/README.md
CHANGED
@@ -19,7 +19,7 @@ TBD: Documentation regarding `DecoLite::Model` options, `DecoLite::Model#load!`
|
|
19
19
|
|
20
20
|
_Deco_ is a little gem that allows you to use the provided `DecoLite::Model` class (`include ActiveModel::Model`) to create Decorator classes which can be instantiated and used. Inherit from `DecoLite::Model` to create your own unique classes with custom functionality. A `DecoLite::Model` includes `ActiveModel::Model`, so validation can be applied using [ActiveModel validation helpers](https://api.rubyonrails.org/v6.1.3/classes/ActiveModel/Validations/HelperMethods.html) you are familiar with; or, you can roll your own - just like any other ActiveModel.
|
21
21
|
|
22
|
-
A `DecoLite::Model` will allow you to consume a Ruby Hash that you supply via the initializer (`DecoLite::Model#new`) or via the `DecoLite::Model#load!` method. Your supplied Ruby Hashes are used to create `attr_accessor` attributes (_"fields"_) on the model. Each attribute created, is then assigned its value from the Hash loaded.
|
22
|
+
A `DecoLite::Model` will allow you to consume a Ruby Hash that you supply via the initializer (`DecoLite::Model#new`) or via the `DecoLite::Model#load!` method. Your supplied Ruby Hashes are used to create `attr_accessor` attributes (_"fields"_) on the model. Each attribute created, is then assigned its value from the Hash loaded. Any number of hashes can be consumed using the `DecoLite::Model#load!` method.
|
23
23
|
|
24
24
|
`attr_accessor` names created are _mangled_ to include namespacing. This creates unique attribute names for nested Hashes that may include non-unique keys. For example:
|
25
25
|
|
@@ -34,7 +34,7 @@ family = {
|
|
34
34
|
}
|
35
35
|
}
|
36
36
|
```
|
37
|
-
Given the above example, DecoLite will produce the following `attr_accessors` on the `DecoLite::Model` object
|
37
|
+
Given the above example, DecoLite will produce the following `attr_accessors` on the `DecoLite::Model` object and assign the values:
|
38
38
|
|
39
39
|
```ruby
|
40
40
|
# Or DecoLite::Model.new.load!(hash: family)
|
@@ -53,17 +53,21 @@ model.wife_age #=> 30
|
|
53
53
|
model.respond_to? :wife_age= #=> true
|
54
54
|
```
|
55
55
|
|
56
|
-
`DecoLite::Model#load!` can be called _multiple times_, on the same model, with different Hashes. This could potentially cause `attr_accessor` name clashes. In order to ensure unique `attr_accessor` names, a _"namespace"_ may be _explicitly_ provided to ensure uniqueness.
|
56
|
+
`DecoLite::Model#load!` can be called _multiple times_, on the same model, with different Hashes. This could potentially cause `attr_accessor` name clashes. In order to ensure unique `attr_accessor` names, a _"namespace"_ may be _explicitly_ provided to ensure uniqueness.
|
57
|
+
|
58
|
+
For example, **continuing from the previous example;** if we were to call `DecoLite::Model#load!` a _second time_ with the following Hash, this would potentially produce `attr_accessor` name clashes:
|
57
59
|
|
58
60
|
```ruby
|
59
61
|
grandpa = {
|
60
62
|
name: 'Henry Doe',
|
61
63
|
age: 85,
|
62
64
|
}
|
63
|
-
# The :name and :age Hash keys above will produce :name/:name= and :age/:age= attr_accessors
|
65
|
+
# The :name and :age Hash keys above will produce :name/:name= and :age/:age= attr_accessors
|
66
|
+
# and clash because these were already added to the model when "John Doe" was loaded with
|
67
|
+
# the first call to DecoLite::Model.new(hash: family).
|
64
68
|
```
|
65
69
|
|
66
|
-
However, passing a `
|
70
|
+
However, passing a `:namespace` option (for example `namespace: :grandpa`) to the `DecoLite::Model#load!` method, would produce the following `attr_accessors`, ensuring their uniqueness:
|
67
71
|
|
68
72
|
```ruby
|
69
73
|
model.load!(hash: grandpa, options: { namespace: :grandpa })
|
@@ -88,6 +92,11 @@ model.respond_to? :wife_name= #=> true
|
|
88
92
|
model.wife_age #=> 30
|
89
93
|
model.respond_to? :wife_age= #=> true
|
90
94
|
```
|
95
|
+
|
96
|
+
### For more examples and usage
|
97
|
+
|
98
|
+
For more examples and usage, see the [Examples and usage](#examples-and-usage) and [Mode examples and usage](#more-examples-and-usage) sections; there is also an "I want to..." section with examples you might encounter when using `DecoLite`.
|
99
|
+
|
91
100
|
## Use cases
|
92
101
|
|
93
102
|
### General
|
@@ -187,7 +196,7 @@ model.wife_info_address #=> 1 street, boonton, nj 07005
|
|
187
196
|
|
188
197
|
#### Add validators to my model
|
189
198
|
|
190
|
-
Simply add your `ActiveModel` validators just like you would any other `ActiveModel::Model` validator. However, be aware that (currently), any attribute (field) having an _explicit validation_ associated with it, will automatically cause an `attr_accessor` to be created for that field; this is to avoid `NoMethodErrors` when calling a validation method on the model (e.g. `#valid?`, `#validate`, etc.)
|
199
|
+
Simply add your `ActiveModel` validators just like you would any other `ActiveModel::Model` validator. However, be aware that (currently), any attribute (field) having an _explicit validation_ associated with it, will automatically cause an `attr_accessor` to be created for that field; this is to avoid `NoMethodErrors` when calling a validation method on the model (e.g. `#valid?`, `#validate`, etc.) *before* the data is loaded to create the associated `attr_accessors`:
|
191
200
|
|
192
201
|
```ruby
|
193
202
|
class Model < DecoLite::Model
|
@@ -212,13 +221,13 @@ model.validate
|
|
212
221
|
|
213
222
|
#### Validate whether or not certain fields were loaded
|
214
223
|
|
215
|
-
To be clear, this
|
224
|
+
To be clear, this example does not validate the _data_ associated with the fields loaded; rather, this example validates whether or not the _fields themselves_ (`attr_accessors`) were created on your model as a result of loading data into your model. If you only want to validate the _data_ loaded into your model, simply add `ActiveModel` validation, just like you would any other `ActiveModel` model, see the [Add validators to my model](#add-validators-to-my-model) section.
|
216
225
|
|
217
|
-
If you want to validate whether or not particular _fields_ were added to your model as attributes (
|
226
|
+
If you want to validate whether or not particular _fields_ were added to your model as attributes (`attr_accessor`), as a result of `#load!`ing data into your model, you need to do a few things:
|
218
227
|
- Create a `DecoLite::Model` subclass.
|
219
228
|
- Override the `DecoLite::Model#required_fields` method to return the field names you want to validate.
|
220
229
|
- Use the `required_fields: nil` option when instantiating your model object.
|
221
|
-
- DO NOT add `ActiveModel` validators that _explicitly_ reference any field returned from `DecoLite::Model#required_fields`; this will cause `attr_accessors` to be created for these fields; consequently, `DecoLite::FieldRequireable#validate_required_fields` will
|
230
|
+
- DO NOT add `ActiveModel` validators that _explicitly_ reference any field returned from `DecoLite::Model#required_fields`; this will cause `attr_accessors` to be created for these fields; consequently, `DecoLite::FieldRequireable#validate_required_fields` will *never* return any errors because these fields will exist as attributes on your model. In other words, do not add (for example) `validates :first, :last, :address, presence: true` to your model if you need to validate whether or not the data you load into your model includs fields `:first`, `:last` and `:address`.
|
222
231
|
|
223
232
|
For example:
|
224
233
|
|
@@ -228,14 +237,15 @@ class Model < DecoLite::Model
|
|
228
237
|
validates :age, numericality: { only_integer: true }, allow_blank: true
|
229
238
|
|
230
239
|
def required_fields
|
231
|
-
# We want to ensure
|
240
|
+
# We want to ensure these fields were included as Hash keys during loading.
|
232
241
|
%i(first last address)
|
233
242
|
end
|
234
243
|
end
|
244
|
+
```
|
245
|
+
|
246
|
+
Option `required_fields: :auto` is the default which will automatically create `attr_accessors` for any field returned from the `DecoLite::Model#required_fields` method; therefore, we need to set the `:required_fields` option to `nil` (i.e. `required_fields: nil`). This will prohibit `DecoLite::Model` from automatically creating `attr_accessors` for `:first`, `:last` and `:address`, and achieve the results we want:
|
235
247
|
|
236
|
-
|
237
|
-
# attr_accessors for fields returned from DecoLite::Model#required_fields, so we
|
238
|
-
# need to set this option to nil (i.e. required_fields: nil).
|
248
|
+
```ruby
|
239
249
|
model = Model.new(options: { required_fields: nil })
|
240
250
|
|
241
251
|
model.validate
|
@@ -243,7 +253,22 @@ model.validate
|
|
243
253
|
model.errors.full_messages
|
244
254
|
#=> ["First field is missing", "Last field is missing", "Address field is missing"]
|
245
255
|
|
246
|
-
|
256
|
+
# If we load data that includes :first, :last, and :address Hash keys even with
|
257
|
+
# nil data, our ":<field> field is missing" errors go away; in this scenario,
|
258
|
+
# we're validating the presence of the FIELDS, not the data associated with
|
259
|
+
# these fields!
|
260
|
+
model.load!(hash: { first: nil, last: nil, address: nil })
|
261
|
+
model.validate
|
262
|
+
#=> true
|
263
|
+
model.errors.full_messages
|
264
|
+
#=> []
|
265
|
+
|
266
|
+
user = {
|
267
|
+
first: 'John',
|
268
|
+
last: 'Doe',
|
269
|
+
address: '123 anystreet, anytown, nj 01234',
|
270
|
+
age: 'x'
|
271
|
+
}
|
247
272
|
model.load!(hash: user)
|
248
273
|
model.validate
|
249
274
|
#=> false
|
@@ -316,19 +341,21 @@ class JustBecauseYouCanDoesntMeanYouShould < DecoLite::Model
|
|
316
341
|
end
|
317
342
|
```
|
318
343
|
|
319
|
-
However, the above is unnecessary as this can be easily accomplished using `DecoLite::Model#load!`:
|
344
|
+
However, the above is unnecessary as this can be easily accomplished by passing a `Hash` to the initializer or by using `DecoLite::Model#load!`:
|
345
|
+
|
320
346
|
```ruby
|
321
|
-
model = Class.new(DecoLite::Model).new
|
347
|
+
model = Class.new(DecoLite::Model).new(hash:{ existing_field: :value })
|
322
348
|
|
323
349
|
model.field_names
|
324
350
|
#=> [:existing_field]
|
325
351
|
|
326
352
|
model.existing_field
|
327
|
-
#=> :
|
353
|
+
#=> :value
|
328
354
|
|
329
355
|
model.respond_to? :existing_field=
|
330
356
|
#=> true
|
331
357
|
```
|
358
|
+
|
332
359
|
## Installation
|
333
360
|
|
334
361
|
Add this line to your application's Gemfile:
|
data/lib/deco_lite/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: deco_lite
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Gene M. Angelo, Jr.
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-08-
|
11
|
+
date: 2022-08-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|