deco_lite 0.3.2 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- 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
|