u-attributes 2.2.0 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|