u-attributes 2.2.0 → 2.3.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 +4 -4
- data/README.md +127 -35
- data/lib/micro/attributes.rb +21 -5
- data/lib/micro/attributes/utils.rb +18 -0
- data/lib/micro/attributes/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: 2f90839cb67a0501e1ef44a5f06a324103063c87e929549377f885504bda5d8a
|
4
|
+
data.tar.gz: fd77058f7e514644a8363d460ad33ad76885648e32b5d9b02e22e592ffbf3ffe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 27401e952c4f5611ec5443df546d4c2c67f0af7aa40606a8e0f128ae37dc167747d0ba4c94008d993d65c886d4e1d66c6ef3472556ecfa353903779f51b4fe23
|
7
|
+
data.tar.gz: d05025bd7442681e14fa8f970fb166898ec9af4a344b8912e10c57f559830833bebe05ccacea85332ef9c88437adabc60152967f8b0b38d01f38f1cc6a7c1257
|
data/README.md
CHANGED
@@ -47,6 +47,15 @@ So, if you change [[1](#with_attribute)] [[2](#with_attributes)] some object att
|
|
47
47
|
- [Is it possible to inherit the attributes?](#is-it-possible-to-inherit-the-attributes)
|
48
48
|
- [`.attribute!()`](#attribute)
|
49
49
|
- [How to query the attributes?](#how-to-query-the-attributes)
|
50
|
+
- [`.attributes`](#attributes)
|
51
|
+
- [`.attribute?()`](#attribute-1)
|
52
|
+
- [`#attribute?()`](#attribute-2)
|
53
|
+
- [`#attributes()`](#attributes-1)
|
54
|
+
- [`#attributes(keys_as:)`](#attributeskeys_as)
|
55
|
+
- [`#attributes(*names)`](#attributesnames)
|
56
|
+
- [`#attributes([names])`](#attributesnames-1)
|
57
|
+
- [`#attributes(with:, without)`](#attributeswith-without)
|
58
|
+
- [`#defined_attributes`](#defined_attributes)
|
50
59
|
- [Built-in extensions](#built-in-extensions)
|
51
60
|
- [Picking specific features](#picking-specific-features)
|
52
61
|
- [`Micro::Attributes.with`](#microattributeswith)
|
@@ -75,7 +84,7 @@ gem 'u-attributes'
|
|
75
84
|
|
76
85
|
| u-attributes | branch | ruby | activemodel |
|
77
86
|
| -------------- | ------- | -------- | ------------- |
|
78
|
-
| 2.
|
87
|
+
| 2.3.0 | main | >= 2.2.0 | >= 3.2, < 6.1 |
|
79
88
|
| 1.2.0 | v1.x | >= 2.2.0 | >= 3.2, < 6.1 |
|
80
89
|
|
81
90
|
> **Note**: The activemodel is an optional dependency, this module [can be enabled](#activemodelvalidation-extension) to validate the attributes.
|
@@ -419,69 +428,152 @@ beta_person.age # 0
|
|
419
428
|
|
420
429
|
## How to query the attributes?
|
421
430
|
|
431
|
+
All of the methods that will be explained can be used with any of the built-in extensions.
|
432
|
+
|
433
|
+
**PS:** We will use the class below for all of the next examples.
|
434
|
+
|
422
435
|
```ruby
|
423
436
|
class Person
|
424
437
|
include Micro::Attributes
|
425
438
|
|
426
439
|
attribute :age
|
427
|
-
attribute :
|
440
|
+
attribute :first_name, default: 'John'
|
441
|
+
attribute :last_name, default: 'Doe'
|
428
442
|
|
429
443
|
def initialize(options)
|
430
444
|
self.attributes = options
|
431
445
|
end
|
446
|
+
|
447
|
+
def name
|
448
|
+
"#{first_name} #{last_name}"
|
449
|
+
end
|
432
450
|
end
|
451
|
+
```
|
433
452
|
|
434
|
-
|
435
|
-
# .attributes() #
|
436
|
-
#---------------#
|
453
|
+
### `.attributes`
|
437
454
|
|
438
|
-
|
455
|
+
Listing all the class attributes.
|
439
456
|
|
440
|
-
|
441
|
-
#
|
442
|
-
|
457
|
+
```ruby
|
458
|
+
Person.attributes # ["age", "first_name", "last_name"]
|
459
|
+
```
|
443
460
|
|
444
|
-
|
445
|
-
Person.attribute?('name') # true
|
446
|
-
Person.attribute?('foo') # false
|
447
|
-
Person.attribute?(:foo) # false
|
461
|
+
### `.attribute?()`
|
448
462
|
|
449
|
-
|
463
|
+
Checking the existence of some attribute.
|
450
464
|
|
451
|
-
|
465
|
+
```ruby
|
466
|
+
Person.attribute?(:first_name) # true
|
467
|
+
Person.attribute?('first_name') # true
|
452
468
|
|
453
|
-
|
454
|
-
#
|
455
|
-
|
469
|
+
Person.attribute?('foo') # false
|
470
|
+
Person.attribute?(:foo) # false
|
471
|
+
```
|
456
472
|
|
457
|
-
|
473
|
+
### `#attribute?()`
|
458
474
|
|
459
|
-
|
460
|
-
|
461
|
-
|
475
|
+
Checking the existence of some attribute in an instance.
|
476
|
+
|
477
|
+
```ruby
|
478
|
+
person = Person.new(age: 20)
|
462
479
|
|
463
480
|
person.attribute?(:name) # true
|
464
481
|
person.attribute?('name') # true
|
482
|
+
|
465
483
|
person.attribute?('foo') # false
|
466
484
|
person.attribute?(:foo) # false
|
485
|
+
```
|
486
|
+
|
487
|
+
### `#attributes()`
|
488
|
+
|
489
|
+
Fetching all the attributes with their values.
|
490
|
+
|
491
|
+
```ruby
|
492
|
+
person1 = Person.new(age: 20)
|
493
|
+
person1.attributes # {"age"=>20, "first_name"=>"John", "last_name"=>"Doe"}
|
494
|
+
|
495
|
+
person2 = Person.new(first_name: 'Rodrigo', last_name: 'Rodrigues')
|
496
|
+
person2.attributes # {"age"=>nil, "first_name"=>"Rodrigo", "last_name"=>"Rodrigues"}
|
497
|
+
```
|
498
|
+
|
499
|
+
#### `#attributes(keys_as:)`
|
500
|
+
|
501
|
+
Use the `keys_as:` option with `Symbol` or `String` to transform the attributes hash keys.
|
502
|
+
|
503
|
+
```ruby
|
504
|
+
person1 = Person.new(age: 20)
|
505
|
+
person1.attributes(keys_as: Symbol) # {:age=>20, :first_name=>"John", :last_name=>"Doe"}
|
467
506
|
|
468
|
-
|
469
|
-
|
470
|
-
|
507
|
+
person2 = Person.new(first_name: 'Rodrigo', last_name: 'Rodrigues')
|
508
|
+
person2.attributes(keys_as: String) # {"age"=>nil, "first_name"=>"Rodrigo", "last_name"=>"Rodrigues"}
|
509
|
+
```
|
471
510
|
|
472
|
-
|
473
|
-
Person.new(name: 'John').attributes # {'age'=>nil, 'name'=>'John'}
|
511
|
+
#### `#attributes(*names)`
|
474
512
|
|
475
|
-
|
476
|
-
# #attributes(*names) #
|
477
|
-
#---------------------#
|
513
|
+
Slices the attributes to include only the given keys (in their types).
|
478
514
|
|
479
|
-
|
480
|
-
|
515
|
+
```ruby
|
516
|
+
person = Person.new(age: 20)
|
517
|
+
|
518
|
+
person.attributes(:age) # {:age => 20}
|
519
|
+
person.attributes(:age, :first_name) # {:age => 20, :first_name => "John"}
|
520
|
+
person.attributes('age', 'last_name') # {"age" => 20, "last_name" => "Doe"}
|
521
|
+
|
522
|
+
person.attributes(:age, 'last_name') # {:age => 20, "last_name" => "Doe"}
|
523
|
+
|
524
|
+
# You could also use the keys_as: option to ensure the same type for all of the hash keys.
|
525
|
+
|
526
|
+
person.attributes(:age, 'last_name', keys_as: Symbol) # {:age=>20, :last_name=>"Doe"}
|
527
|
+
```
|
528
|
+
|
529
|
+
#### `#attributes([names])`
|
530
|
+
|
531
|
+
As the previous example, this methods accepts a list of keys to slice the attributes.
|
532
|
+
|
533
|
+
```ruby
|
534
|
+
person = Person.new(age: 20)
|
535
|
+
|
536
|
+
person.attributes([:age]) # {:age => 20}
|
537
|
+
person.attributes([:age, :first_name]) # {:age => 20, :first_name => "John"}
|
538
|
+
person.attributes(['age', 'last_name']) # {"age" => 20, "last_name" => "Doe"}
|
539
|
+
|
540
|
+
person.attributes([:age, 'last_name']) # {:age => 20, "last_name" => "Doe"}
|
541
|
+
|
542
|
+
# You could also use the keys_as: option to ensure the same type for all of the hash keys.
|
543
|
+
|
544
|
+
person.attributes([:age, 'last_name'], keys_as: Symbol) # {:age=>20, :last_name=>"Doe"}
|
545
|
+
```
|
546
|
+
|
547
|
+
#### `#attributes(with:, without)`
|
548
|
+
|
549
|
+
Use the `with:` option to include any method value of the instance inside of the hash, and,
|
550
|
+
you can use the `without:` option to exclude one or more attribute keys from the final hash.
|
551
|
+
|
552
|
+
```ruby
|
553
|
+
person = Person.new(age: 20)
|
554
|
+
|
555
|
+
person.attributes(without: :age) # {"first_name"=>"John", "last_name"=>"Doe"}
|
556
|
+
person.attributes(without: [:age, :last_name]) # {"first_name"=>"John"}
|
557
|
+
|
558
|
+
person.attributes(with: [:name], without: [:first_name, :last_name]) # {"age"=>20, "name"=>"John Doe"}
|
559
|
+
|
560
|
+
# To achieves the same output of the previous example, use the attribute names to slice only them.
|
561
|
+
|
562
|
+
person.attributes(:age, with: [:name]) # {:age=>20, "name"=>"John Doe"}
|
563
|
+
|
564
|
+
# You could also use the keys_as: option to ensure the same type for all of the hash keys.
|
565
|
+
|
566
|
+
person.attributes(:age, with: [:name], keys_as: Symbol) # {:age=>20, :name=>"John Doe"}
|
567
|
+
```
|
568
|
+
|
569
|
+
### `#defined_attributes`
|
570
|
+
|
571
|
+
Listing all the available attributes.
|
572
|
+
|
573
|
+
```ruby
|
574
|
+
person = Person.new(age: 20)
|
481
575
|
|
482
|
-
person.
|
483
|
-
person.attributes(:age, :name) # {age: 20, name: 'John Doe'}
|
484
|
-
person.attributes('age', 'name') # {'age'=>20, 'name'=>'John Doe'}
|
576
|
+
person.defined_attributes # ["age", "first_name", "last_name"]
|
485
577
|
```
|
486
578
|
|
487
579
|
[⬆️ Back to Top](#table-of-contents-)
|
data/lib/micro/attributes.rb
CHANGED
@@ -55,16 +55,32 @@ module Micro
|
|
55
55
|
raise NameError, "undefined attribute `#{name}"
|
56
56
|
end
|
57
57
|
|
58
|
+
def defined_attributes
|
59
|
+
@defined_attributes ||= self.class.attributes
|
60
|
+
end
|
61
|
+
|
58
62
|
def attributes(*names)
|
59
63
|
return __attributes if names.empty?
|
60
64
|
|
61
|
-
names.
|
62
|
-
|
65
|
+
options = names.last.is_a?(Hash) ? names.pop : Kind::Empty::HASH
|
66
|
+
|
67
|
+
names.flatten!
|
68
|
+
|
69
|
+
without_option = Array(options.fetch(:without, Kind::Empty::ARRAY))
|
70
|
+
|
71
|
+
keys = names.empty? ? defined_attributes - without_option.map(&:to_s) : names - without_option
|
72
|
+
|
73
|
+
data = keys.each_with_object({}) { |key, memo| memo[key] = attribute(key) if attribute?(key) }
|
74
|
+
|
75
|
+
with_option = Array(options.fetch(:with, Kind::Empty::ARRAY))
|
76
|
+
|
77
|
+
unless with_option.empty?
|
78
|
+
extra = with_option.each_with_object({}) { |key, memo| memo[key.to_s] = public_send(key) }
|
79
|
+
|
80
|
+
data.merge!(extra)
|
63
81
|
end
|
64
|
-
end
|
65
82
|
|
66
|
-
|
67
|
-
@defined_attributes ||= self.class.attributes
|
83
|
+
Utils::Hashes.keys_as(options[:keys_as], data)
|
68
84
|
end
|
69
85
|
|
70
86
|
protected
|
@@ -12,6 +12,24 @@ module Micro::Attributes
|
|
12
12
|
hash.each_with_object({}) { |(key, val), memo| memo[key.to_s] = val }
|
13
13
|
end
|
14
14
|
|
15
|
+
def self.symbolize_keys(arg)
|
16
|
+
hash = Kind::Of.(::Hash, arg)
|
17
|
+
|
18
|
+
return hash if hash.empty?
|
19
|
+
return hash.transform_keys(&:to_sym) if hash.respond_to?(:transform_keys)
|
20
|
+
|
21
|
+
hash.each_with_object({}) { |(key, val), memo| memo[key.to_sym] = val }
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.keys_as(type, hash)
|
25
|
+
return Kind::Of.(::Hash, hash) unless type
|
26
|
+
|
27
|
+
return symbolize_keys(hash) if type == Symbol
|
28
|
+
return stringify_keys(hash) if type == String
|
29
|
+
|
30
|
+
raise ArgumentError, 'first argument must be the class String or Symbol'.freeze
|
31
|
+
end
|
32
|
+
|
15
33
|
def self.get(hash, key)
|
16
34
|
value = hash[key.to_s]
|
17
35
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: u-attributes
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rodrigo Serradura
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-09-
|
11
|
+
date: 2020-09-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: kind
|