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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: b5b5ed040bd367962dd57760a6a0e572b60485ba1d2d3630980ff1a090ca9075
4
- data.tar.gz: 76402762f17d93fd53495ddabf86487803b0014971db007f61f505727e933f56
3
+ metadata.gz: 77c440561731ca11332b76f0ee373e4568d4e84c11930d530d1dde9d5c097eb9
4
+ data.tar.gz: f771f70f192ae1c2b2d7a935933f7157cde64c6f44e9dc60d50e66d58e8abb05
5
5
  SHA512:
6
- metadata.gz: 584e1c07a160370bc9548e7a41dbaa9adcbee757a35a37925d02accf4ebe71d24cd9d2932e706724f5d8d64e8d98ff77f223224de27e5a0d817eb2675fea81ca
7
- data.tar.gz: 6a49a3ab8bdcb947341697577e130dd667c508095578536e8d003cfa1424f8e090f3c40e9ddc1376a3337cdcc9a26a02e836bc901c0ae36da39a8acaaae8cc46
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.1)
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.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.0)
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 when loaded, and assign the values:
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. For example, continuing from the previous example; if we were to call `DecoLite::Model#load!` a _second time_ with the following Hash, it would produce `attr_accessor` name clashes:
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 and clash because these were already added to the model when "John Doe" was loaded with the first call to DecoLite::Model.new(hash: family).
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 `namespace:` option (for example `namespace: :grandpa`) to the `DecoLite::Model#load!` method, would produce the following `attr_accessors`, ensuring their uniqueness:
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 has nothing to do with the _data_ associated with the fields loaded; rather, this has to do with whether or not the _fields themselves_ were created as attributes on your model as a result of loading data into your model. If you simply 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.
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 (i.e. `attr_accessor`), as a result of `#load!`ing data into your model, you need to do a few things:
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 _never_ return any errors because these fields will exist as attributes on your model. In other words, do not add `validates :first, :last, :address, presence: true` to your model if you need to validate whether or not the data you load into your model included fields :first, :last and :address.
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 attr_accessors are created for these fields.
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
- # Option "required_fields: :auto" is the default which will automatically create
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
- user = { first: 'John', last: 'Doe', address: '123 anystreet, anytown, nj 01234'}
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.load!(hash:{ existing_field: :existing_field_value })
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
- #=> :existing_field_value
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:
@@ -2,5 +2,5 @@
2
2
 
3
3
  # Defines the version of this gem.
4
4
  module DecoLite
5
- VERSION = '0.3.2'
5
+ VERSION = '0.3.3'
6
6
  end
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.2
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-29 00:00:00.000000000 Z
11
+ date: 2022-08-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel