deco_lite 0.3.0 → 0.3.1
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/CHANGELOG.md +5 -0
- data/Gemfile.lock +1 -1
- data/README.md +98 -5
- data/lib/deco_lite/field_requireable.rb +3 -1
- 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: 8a87d5a79f738b49d45b51c0128b4c252853c683363e7525df836fc7c46e4953
|
4
|
+
data.tar.gz: 1f07c897d0f88cd3609a8e6a880d0ce91b71210ee8952eb29148370b2f49f092
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: afc6320e0a1e9060dda231249fe16e62bf62d56f11ad7ffa9c4c6a0f094ef866173655c4ee57a419b3c4b83d0d7b7639230db22459f3c2d81d78cc6c4da2dde2
|
7
|
+
data.tar.gz: 6db8e3cb9a634669667eb288f4a4343106ad9be71630c1a9e95af366649b86e88459d0b79f1c71e09345a75805e643aa1e1e3a2836e2045bd1191bd78484685c
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
### 0.3.1
|
2
|
+
* Changes
|
3
|
+
* Added `DecoLite::FieldRequireable::MISSING_REQUIRED_FIELD_ERROR_TYPE` for required field type errors.
|
4
|
+
* Update README.md with more examples.
|
5
|
+
|
1
6
|
### 0.3.0
|
2
7
|
* Changes
|
3
8
|
* `DecoLite::Model#new` how accepts a :hash named parameter that will load the Hash as if calling `DecoLite::Model.new.load!(hash: <hash>)`.
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -188,24 +188,117 @@ model.wife_info_address #=> 1 street, boonton, nj 07005
|
|
188
188
|
|
189
189
|
#### Add validators to my model
|
190
190
|
|
191
|
-
Simply add your `ActiveModel` validators just like you would any other `ActiveModel::Model` validator. However, be aware that (currently), any attribute (field)
|
191
|
+
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.):
|
192
192
|
|
193
193
|
```ruby
|
194
194
|
class Model < DecoLite::Model
|
195
195
|
validates :first, :last, :address, presence: true
|
196
|
+
validates :age, numericality: true
|
196
197
|
end
|
197
198
|
|
198
|
-
|
199
|
+
# No :address
|
200
|
+
model = Model.new(hash: { first: 'John', last: 'Doe', age: 25 })
|
201
|
+
model.respond_to? :address
|
202
|
+
#=> true
|
199
203
|
|
200
|
-
|
201
|
-
|
202
|
-
|
204
|
+
model.valid?
|
205
|
+
#=> false
|
206
|
+
model.errors.full_messages
|
207
|
+
#=> ["Address can't be blank"]
|
203
208
|
|
204
209
|
model.load!(hash: { address: '123 park road, anytown, nj 01234' })
|
205
210
|
model.validate
|
206
211
|
#=> true
|
207
212
|
```
|
208
213
|
|
214
|
+
#### Validate whether or not certain fields were loaded
|
215
|
+
|
216
|
+
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.
|
217
|
+
|
218
|
+
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:
|
219
|
+
- Create a `DecoLite::Model` subclass.
|
220
|
+
- Override the `DecoLite::Model#required_fields` method to return the field names you want to validate.
|
221
|
+
- Use the `required_fields: nil` option when instantiating your model object.
|
222
|
+
- 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.
|
223
|
+
|
224
|
+
For example:
|
225
|
+
|
226
|
+
```ruby
|
227
|
+
class Model < DecoLite::Model
|
228
|
+
# :age field is optional and it's value is optional.
|
229
|
+
validates :age, numericality: { only_integer: true }, allow_blank: true
|
230
|
+
|
231
|
+
def required_fields
|
232
|
+
# We want to ensure attr_accessors are created for these fields.
|
233
|
+
%i(first last address)
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
# Option "required_fields: :auto" is the default which will automatically create
|
238
|
+
# attr_accessors for fields returned from DecoLite::Model#required_fields, so we
|
239
|
+
# need to set this option to nil (i.e. required_fields: nil).
|
240
|
+
model = Model.new(options: { required_fields: nil })
|
241
|
+
|
242
|
+
model.validate
|
243
|
+
#=> false
|
244
|
+
model.errors.full_messages
|
245
|
+
#=> ["First field is missing", "Last field is missing", "Address field is missing"]
|
246
|
+
|
247
|
+
user = { first: 'John', last: 'Doe', address: '123 anystreet, anytown, nj 01234'}
|
248
|
+
model.load!(hash: user)
|
249
|
+
model.validate
|
250
|
+
#=> false
|
251
|
+
model.errors.full_messages
|
252
|
+
#=> ["Age is not a number"]
|
253
|
+
```
|
254
|
+
#### Validate whether or not certain fields were loaded _and_ validate the data associated with these same fields
|
255
|
+
|
256
|
+
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.
|
257
|
+
|
258
|
+
If you want to validate whether or not particular fields were loaded _and_ field data associated with these same fields, you'll have to use custom validation (e.g. override `DecoLite::FieldRequireable#validate_required_fields` and manually add your own validation and errors). This is because `DecoLite::Model#new` will automatically create `attr_accessors` for any attribute (field) that has an _explicit_ `ActiveModel` validation associated with it, and return false positives when you validate your model. In addition to this, you will need to do several other things outlined in the [Validate whether or not certain fields were loaded](#validate-whether-or-not-certain-fields-were-loaded) section.
|
259
|
+
|
260
|
+
For example:
|
261
|
+
|
262
|
+
```ruby
|
263
|
+
class Model < DecoLite::Model
|
264
|
+
def required_fields
|
265
|
+
%i(first last address age)
|
266
|
+
end
|
267
|
+
|
268
|
+
def validate_required_fields
|
269
|
+
super
|
270
|
+
|
271
|
+
first = self.try(:first)
|
272
|
+
errors.add(:first, "can't be blank") if first.nil?
|
273
|
+
|
274
|
+
last = self.try(:last)
|
275
|
+
errors.add(:last, "can't be blank") if last.nil?
|
276
|
+
|
277
|
+
address = self.try(:address)
|
278
|
+
errors.add(:address, "can't be blank") if address.nil?
|
279
|
+
|
280
|
+
age = self.try(:age)
|
281
|
+
errors.add(:age, "can't be blank") if age.nil?
|
282
|
+
errors.add(:age, 'is not a number') unless /\d+/ =~ age
|
283
|
+
end
|
284
|
+
end
|
285
|
+
model = Model.new(options: { required_fields: nil })
|
286
|
+
|
287
|
+
model.validate
|
288
|
+
#=> false
|
289
|
+
|
290
|
+
model.errors.full_messages
|
291
|
+
#=> ["First field is missing",
|
292
|
+
"Last field is missing",
|
293
|
+
"Address field is missing",
|
294
|
+
"Age field is missing",
|
295
|
+
"First can't be blank",
|
296
|
+
"Last can't be blank",
|
297
|
+
"Address can't be blank",
|
298
|
+
"Age can't be blank",
|
299
|
+
"Age is not a number"]
|
300
|
+
```
|
301
|
+
|
209
302
|
#### Manually define attributes (fields) on my model
|
210
303
|
|
211
304
|
Manually defining attributes on your subclass is possible, although there doesn't seem a valid reason to do so, since you can just use `DecoLite::Model#load!` to wire all this up for you automatically. However, if there _were_ a need to do this, you must add your `attr_reader` to the `DecoLite::Model@field_names` array, or an error will be raised _provided_ there are any conflicting field names being loaded using `DecoLite::Model#load!`. Note that the aforementioned error will be raised regardless of whether or not you set `options: { fields: :merge }`. This is because DecoLite considers any existing model attributes _not_ added to the model via `load!`to be native to the model object, and therefore will not allow you to create attr_accessors for existing model attributes because this can potentially be dangerous.
|
@@ -4,6 +4,8 @@ module DecoLite
|
|
4
4
|
# Provides methods to manage fields that must be defined from
|
5
5
|
# the dynamically loaded data.
|
6
6
|
module FieldRequireable
|
7
|
+
MISSING_REQUIRED_FIELD_ERROR_TYPE = :missing_required_field
|
8
|
+
|
7
9
|
# Returns field names that will be used to validate the presence of
|
8
10
|
# dynamically created fields from loaded objects.
|
9
11
|
#
|
@@ -23,7 +25,7 @@ module DecoLite
|
|
23
25
|
required_fields.each do |field_name|
|
24
26
|
next if required_field_exist? field_name: field_name
|
25
27
|
|
26
|
-
errors.add(field_name, 'field is missing', type:
|
28
|
+
errors.add(field_name, 'field is missing', type: MISSING_REQUIRED_FIELD_ERROR_TYPE)
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
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.1
|
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-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activemodel
|