enumerate_it 4.1.0 → 4.2.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/.github/workflows/ci.yml +16 -3
- data/.prettierrc.json +4 -0
- data/.rubocop.yml +6 -2
- data/Appraisals +1 -1
- data/Gemfile.lock +53 -47
- data/README.md +102 -10
- data/enumerate_it.gemspec +1 -1
- data/gemfiles/rails_7.0.gemfile +2 -2
- data/gemfiles/rails_7.1.gemfile +2 -2
- data/gemfiles/rails_7.2.gemfile +2 -2
- data/gemfiles/rails_8.0.gemfile +2 -2
- data/gemfiles/rails_8.1.gemfile +9 -0
- data/lib/enumerate_it/base.rb +22 -5
- data/lib/enumerate_it/class_methods.rb +19 -3
- data/lib/enumerate_it/version.rb +1 -1
- data/spec/enumerate_it/base_spec.rb +51 -2
- data/spec/enumerate_it_spec.rb +74 -1
- data/spec/support/test_classes.rb +14 -0
- metadata +8 -6
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 9bfa9b8d0d7c06bf9c2d19dd7a41824a27a5e8e4ed6c8ba5cdc8a32b4ea1fb79
|
|
4
|
+
data.tar.gz: 1b34d10ee5220f0e123cfb3479bca25e319f78fd6d98a39edb35d73385d3d11d
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: c2021954323a6cb5b9c16534998bf240036dad2ba1af4c78936af9048f6ee1dd105d99340300684e72a6182e9fe75134fe2df88a3da1fddf86564d078cfcb3f3
|
|
7
|
+
data.tar.gz: 339d92259a7fa059dd10e5a4531a76005524e0ce34fe921c6f11a4de0108efa3f94aa827ef30ebb4b1c75fbdbc07b7735195f0aae81fd7c569817ee85ddd937c
|
data/.github/workflows/ci.yml
CHANGED
|
@@ -14,6 +14,7 @@ jobs:
|
|
|
14
14
|
- 3.2
|
|
15
15
|
- 3.3
|
|
16
16
|
- 3.4
|
|
17
|
+
- 4.0
|
|
17
18
|
gemfile:
|
|
18
19
|
- gemfiles/rails_6.0.gemfile
|
|
19
20
|
- gemfiles/rails_6.1.gemfile
|
|
@@ -21,12 +22,24 @@ jobs:
|
|
|
21
22
|
- gemfiles/rails_7.1.gemfile
|
|
22
23
|
- gemfiles/rails_7.2.gemfile
|
|
23
24
|
- gemfiles/rails_8.0.gemfile
|
|
25
|
+
- gemfiles/rails_8.1.gemfile
|
|
24
26
|
exclude:
|
|
25
|
-
# Rails 8 requires Ruby 3.2 or newer
|
|
27
|
+
# Rails 8+ requires Ruby 3.2 or newer
|
|
26
28
|
- ruby: 3.0
|
|
27
29
|
gemfile: gemfiles/rails_8.0.gemfile
|
|
30
|
+
- ruby: 3.0
|
|
31
|
+
gemfile: gemfiles/rails_8.1.gemfile
|
|
28
32
|
- ruby: 3.1
|
|
29
33
|
gemfile: gemfiles/rails_8.0.gemfile
|
|
34
|
+
- ruby: 3.1
|
|
35
|
+
gemfile: gemfiles/rails_8.1.gemfile
|
|
36
|
+
# Rails 6.x and 7.0 are EOL and don't support Ruby 4+
|
|
37
|
+
- ruby: 4.0
|
|
38
|
+
gemfile: gemfiles/rails_6.0.gemfile
|
|
39
|
+
- ruby: 4.0
|
|
40
|
+
gemfile: gemfiles/rails_6.1.gemfile
|
|
41
|
+
- ruby: 4.0
|
|
42
|
+
gemfile: gemfiles/rails_7.0.gemfile
|
|
30
43
|
|
|
31
44
|
env:
|
|
32
45
|
BUNDLE_GEMFILE: "${{ matrix.gemfile }}"
|
|
@@ -35,7 +48,7 @@ jobs:
|
|
|
35
48
|
|
|
36
49
|
steps:
|
|
37
50
|
- name: Checkout
|
|
38
|
-
uses: actions/checkout@
|
|
51
|
+
uses: actions/checkout@v6
|
|
39
52
|
- name: Set up Ruby
|
|
40
53
|
uses: ruby/setup-ruby@v1
|
|
41
54
|
with:
|
|
@@ -43,7 +56,7 @@ jobs:
|
|
|
43
56
|
bundler-cache: true
|
|
44
57
|
|
|
45
58
|
- name: Rubocop
|
|
46
|
-
if: ${{ matrix.ruby == '
|
|
59
|
+
if: ${{ matrix.ruby == '4.0' }}
|
|
47
60
|
run: "bundle exec rubocop"
|
|
48
61
|
|
|
49
62
|
- name: Tests
|
data/.prettierrc.json
ADDED
data/.rubocop.yml
CHANGED
|
@@ -8,7 +8,7 @@ inherit_mode:
|
|
|
8
8
|
|
|
9
9
|
AllCops:
|
|
10
10
|
NewCops: enable
|
|
11
|
-
TargetRubyVersion: 3.
|
|
11
|
+
TargetRubyVersion: 3.0 # Keep in sync with `required_ruby_version` in the gemspec.
|
|
12
12
|
|
|
13
13
|
Exclude:
|
|
14
14
|
- 'lib/generators/enumerate_it/enum/templates/**/*'
|
|
@@ -67,7 +67,11 @@ Style/HashTransformKeys:
|
|
|
67
67
|
Style/HashTransformValues:
|
|
68
68
|
Enabled: true
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
Style/OneClassPerFile:
|
|
71
|
+
Exclude:
|
|
72
|
+
- 'spec/support//**/*'
|
|
73
|
+
|
|
74
|
+
Naming/PredicatePrefix:
|
|
71
75
|
Exclude:
|
|
72
76
|
- 'lib/enumerate_it/class_methods.rb'
|
|
73
77
|
|
data/Appraisals
CHANGED
|
@@ -4,7 +4,7 @@ require 'json'
|
|
|
4
4
|
rails_versions = JSON.parse(Net::HTTP.get(URI('https://rubygems.org/api/v1/versions/rails.json')))
|
|
5
5
|
.group_by { |version| version['number'] }.keys.grep_v(/rc|racecar|alpha|beta|pre/)
|
|
6
6
|
|
|
7
|
-
%w[6.0 6.1 7.0 7.1 7.2 8.0].each do |rails_version|
|
|
7
|
+
%w[6.0 6.1 7.0 7.1 7.2 8.0 8.1].each do |rails_version|
|
|
8
8
|
appraise "rails_#{rails_version}" do
|
|
9
9
|
current_version = rails_versions
|
|
10
10
|
.select { |key| key.match(/\A#{rails_version}/) }
|
data/Gemfile.lock
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
enumerate_it (4.
|
|
4
|
+
enumerate_it (4.2.0)
|
|
5
5
|
activesupport (>= 6.0.0)
|
|
6
6
|
|
|
7
7
|
GEM
|
|
8
8
|
remote: https://rubygems.org/
|
|
9
9
|
specs:
|
|
10
|
-
activemodel (8.
|
|
11
|
-
activesupport (= 8.
|
|
12
|
-
activerecord (8.
|
|
13
|
-
activemodel (= 8.
|
|
14
|
-
activesupport (= 8.
|
|
10
|
+
activemodel (8.1.3)
|
|
11
|
+
activesupport (= 8.1.3)
|
|
12
|
+
activerecord (8.1.3)
|
|
13
|
+
activemodel (= 8.1.3)
|
|
14
|
+
activesupport (= 8.1.3)
|
|
15
15
|
timeout (>= 0.4.0)
|
|
16
|
-
activesupport (8.
|
|
16
|
+
activesupport (8.1.3)
|
|
17
17
|
base64
|
|
18
|
-
benchmark (>= 0.3)
|
|
19
18
|
bigdecimal
|
|
20
19
|
concurrent-ruby (~> 1.0, >= 1.3.1)
|
|
21
20
|
connection_pool (>= 2.2.5)
|
|
22
21
|
drb
|
|
23
22
|
i18n (>= 1.6, < 2)
|
|
23
|
+
json
|
|
24
24
|
logger (>= 1.4.2)
|
|
25
25
|
minitest (>= 5.1)
|
|
26
26
|
securerandom (>= 0.3)
|
|
@@ -31,80 +31,86 @@ GEM
|
|
|
31
31
|
rake
|
|
32
32
|
thor (>= 0.14.0)
|
|
33
33
|
ast (2.4.3)
|
|
34
|
-
base64 (0.
|
|
35
|
-
|
|
36
|
-
bigdecimal (3.1.9)
|
|
34
|
+
base64 (0.3.0)
|
|
35
|
+
bigdecimal (4.1.2)
|
|
37
36
|
coderay (1.1.3)
|
|
38
|
-
concurrent-ruby (1.3.
|
|
39
|
-
connection_pool (
|
|
40
|
-
diff-lcs (1.6.
|
|
41
|
-
drb (2.2.
|
|
42
|
-
i18n (1.14.
|
|
37
|
+
concurrent-ruby (1.3.6)
|
|
38
|
+
connection_pool (3.0.2)
|
|
39
|
+
diff-lcs (1.6.2)
|
|
40
|
+
drb (2.2.3)
|
|
41
|
+
i18n (1.14.8)
|
|
43
42
|
concurrent-ruby (~> 1.0)
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
io-console (0.8.2)
|
|
44
|
+
json (2.19.8)
|
|
45
|
+
language_server-protocol (3.17.0.5)
|
|
46
46
|
lint_roller (1.1.0)
|
|
47
47
|
logger (1.7.0)
|
|
48
48
|
method_source (1.1.0)
|
|
49
|
-
mini_portile2 (2.8.
|
|
50
|
-
minitest (
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
mini_portile2 (2.8.9)
|
|
50
|
+
minitest (6.0.6)
|
|
51
|
+
drb (~> 2.0)
|
|
52
|
+
prism (~> 1.5)
|
|
53
|
+
parallel (2.1.0)
|
|
54
|
+
parser (3.3.11.1)
|
|
53
55
|
ast (~> 2.4.1)
|
|
54
56
|
racc
|
|
55
|
-
prism (1.
|
|
56
|
-
pry (0.
|
|
57
|
+
prism (1.9.0)
|
|
58
|
+
pry (0.16.0)
|
|
57
59
|
coderay (~> 1.1)
|
|
58
60
|
method_source (~> 1.0)
|
|
61
|
+
reline (>= 0.6.0)
|
|
59
62
|
racc (1.8.1)
|
|
60
63
|
rainbow (3.1.1)
|
|
61
|
-
rake (13.2
|
|
62
|
-
regexp_parser (2.
|
|
63
|
-
|
|
64
|
+
rake (13.4.2)
|
|
65
|
+
regexp_parser (2.12.0)
|
|
66
|
+
reline (0.6.3)
|
|
67
|
+
io-console (~> 0.5)
|
|
68
|
+
rspec (3.13.2)
|
|
64
69
|
rspec-core (~> 3.13.0)
|
|
65
70
|
rspec-expectations (~> 3.13.0)
|
|
66
71
|
rspec-mocks (~> 3.13.0)
|
|
67
|
-
rspec-core (3.13.
|
|
72
|
+
rspec-core (3.13.6)
|
|
68
73
|
rspec-support (~> 3.13.0)
|
|
69
|
-
rspec-expectations (3.13.
|
|
74
|
+
rspec-expectations (3.13.5)
|
|
70
75
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
71
76
|
rspec-support (~> 3.13.0)
|
|
72
|
-
rspec-mocks (3.13.
|
|
77
|
+
rspec-mocks (3.13.8)
|
|
73
78
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
74
79
|
rspec-support (~> 3.13.0)
|
|
75
|
-
rspec-support (3.13.
|
|
76
|
-
rubocop (1.
|
|
80
|
+
rspec-support (3.13.7)
|
|
81
|
+
rubocop (1.87.0)
|
|
77
82
|
json (~> 2.3)
|
|
78
83
|
language_server-protocol (~> 3.17.0.2)
|
|
79
84
|
lint_roller (~> 1.1.0)
|
|
80
|
-
parallel (
|
|
85
|
+
parallel (>= 1.10)
|
|
81
86
|
parser (>= 3.3.0.2)
|
|
82
87
|
rainbow (>= 2.2.2, < 4.0)
|
|
83
88
|
regexp_parser (>= 2.9.3, < 3.0)
|
|
84
|
-
rubocop-ast (>= 1.
|
|
89
|
+
rubocop-ast (>= 1.49.0, < 2.0)
|
|
85
90
|
ruby-progressbar (~> 1.7)
|
|
86
91
|
unicode-display_width (>= 2.4.0, < 4.0)
|
|
87
|
-
rubocop-ast (1.
|
|
92
|
+
rubocop-ast (1.49.1)
|
|
88
93
|
parser (>= 3.3.7.2)
|
|
89
|
-
prism (~> 1.
|
|
94
|
+
prism (~> 1.7)
|
|
90
95
|
rubocop-rake (0.7.1)
|
|
91
96
|
lint_roller (~> 1.1)
|
|
92
97
|
rubocop (>= 1.72.1)
|
|
93
|
-
rubocop-rspec (3.
|
|
98
|
+
rubocop-rspec (3.10.2)
|
|
94
99
|
lint_roller (~> 1.1)
|
|
95
|
-
|
|
100
|
+
regexp_parser (>= 2.0)
|
|
101
|
+
rubocop (~> 1.86, >= 1.86.2)
|
|
96
102
|
ruby-progressbar (1.13.0)
|
|
97
103
|
securerandom (0.4.1)
|
|
98
|
-
sqlite3 (
|
|
104
|
+
sqlite3 (2.9.5)
|
|
99
105
|
mini_portile2 (~> 2.8.0)
|
|
100
|
-
thor (1.
|
|
101
|
-
timeout (0.
|
|
106
|
+
thor (1.5.0)
|
|
107
|
+
timeout (0.6.1)
|
|
102
108
|
tzinfo (2.0.6)
|
|
103
109
|
concurrent-ruby (~> 1.0)
|
|
104
|
-
unicode-display_width (3.
|
|
105
|
-
unicode-emoji (~> 4.
|
|
106
|
-
unicode-emoji (4.0
|
|
107
|
-
uri (1.
|
|
110
|
+
unicode-display_width (3.2.0)
|
|
111
|
+
unicode-emoji (~> 4.1)
|
|
112
|
+
unicode-emoji (4.2.0)
|
|
113
|
+
uri (1.1.1)
|
|
108
114
|
|
|
109
115
|
PLATFORMS
|
|
110
116
|
ruby
|
|
@@ -120,7 +126,7 @@ DEPENDENCIES
|
|
|
120
126
|
rubocop
|
|
121
127
|
rubocop-rake
|
|
122
128
|
rubocop-rspec
|
|
123
|
-
sqlite3
|
|
129
|
+
sqlite3
|
|
124
130
|
|
|
125
131
|
BUNDLED WITH
|
|
126
|
-
|
|
132
|
+
4.0.3
|
data/README.md
CHANGED
|
@@ -17,6 +17,32 @@ This means you can add it to any **Ruby** project! Secondly, you can
|
|
|
17
17
|
[define your enumerations in classes](#creating-enumerations), allowing you to
|
|
18
18
|
**add behavior** and **reuse** them! 😀
|
|
19
19
|
|
|
20
|
+
At a glance:
|
|
21
|
+
|
|
22
|
+
```ruby
|
|
23
|
+
class RelationshipStatus < EnumerateIt::Base
|
|
24
|
+
associate_values :single, :married, :divorced
|
|
25
|
+
|
|
26
|
+
custom_helpers do
|
|
27
|
+
def ever_married?(value)
|
|
28
|
+
[MARRIED, DIVORCED].include?(value)
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
class Person < ApplicationRecord
|
|
34
|
+
has_enumeration_for :relationship_status, create_helpers: true, create_scopes: true
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
person = Person.new(relationship_status: RelationshipStatus::MARRIED)
|
|
38
|
+
|
|
39
|
+
person.married? #=> true
|
|
40
|
+
person.ever_married? #=> true
|
|
41
|
+
person.relationship_status_humanize #=> 'Married'
|
|
42
|
+
Person.married.to_sql #=> SELECT "people".* FROM "people" WHERE "people"."relationship_status" = "married"
|
|
43
|
+
RelationshipStatus.to_a #=> [['Divorced', 'divorced'], ['Married', 'married'], ['Single', 'single']]
|
|
44
|
+
```
|
|
45
|
+
|
|
20
46
|
---
|
|
21
47
|
|
|
22
48
|
<!-- Tocer[start]: Auto-generated, don't remove. -->
|
|
@@ -206,10 +232,13 @@ class Person
|
|
|
206
232
|
end
|
|
207
233
|
```
|
|
208
234
|
|
|
209
|
-
|
|
210
|
-
>
|
|
235
|
+
<!-- prettier-ignore -->
|
|
236
|
+
> [!NOTE]
|
|
237
|
+
> If the enumeration class name differs from the attribute name, use the `with` option:
|
|
211
238
|
>
|
|
212
|
-
>
|
|
239
|
+
> ```ruby
|
|
240
|
+
> has_enumeration_for :relationship_status, with: RelationshipStatus
|
|
241
|
+
> ```
|
|
213
242
|
|
|
214
243
|
This will create:
|
|
215
244
|
|
|
@@ -229,7 +258,7 @@ This will create:
|
|
|
229
258
|
p = Person.new
|
|
230
259
|
p.relationship_status = RelationshipStatus::DIVORCED
|
|
231
260
|
p.relationship_status_humanize
|
|
232
|
-
#=> 'Divorciado'
|
|
261
|
+
#=> 'Divorciado' # with a pt-BR locale loaded
|
|
233
262
|
```
|
|
234
263
|
|
|
235
264
|
- The associated enumerations, which can be retrieved with the `enumerations`
|
|
@@ -335,6 +364,63 @@ This will create:
|
|
|
335
364
|
#=> true
|
|
336
365
|
```
|
|
337
366
|
|
|
367
|
+
<!-- prettier-ignore -->
|
|
368
|
+
> [!IMPORTANT]
|
|
369
|
+
> On ActiveRecord objects, mutator methods like `married!` call `save!`
|
|
370
|
+
> immediately, running callbacks and raising on validation failure. They are
|
|
371
|
+
> not pure setters.
|
|
372
|
+
|
|
373
|
+
You can also define custom helper methods on the enumeration class using
|
|
374
|
+
a `custom_helpers` block:
|
|
375
|
+
|
|
376
|
+
```ruby
|
|
377
|
+
class RelationshipStatus < EnumerateIt::Base
|
|
378
|
+
associate_values :single, :married, :divorced
|
|
379
|
+
|
|
380
|
+
custom_helpers do
|
|
381
|
+
def ever_married?(value)
|
|
382
|
+
[MARRIED, DIVORCED].include?(value)
|
|
383
|
+
end
|
|
384
|
+
end
|
|
385
|
+
end
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
These become class methods on the enumeration:
|
|
389
|
+
|
|
390
|
+
```ruby
|
|
391
|
+
RelationshipStatus.ever_married?(RelationshipStatus::MARRIED) #=> true
|
|
392
|
+
RelationshipStatus.ever_married?(RelationshipStatus::DIVORCED) #=> true
|
|
393
|
+
RelationshipStatus.ever_married?(RelationshipStatus::SINGLE) #=> false
|
|
394
|
+
```
|
|
395
|
+
|
|
396
|
+
When `create_helpers: true` is used, they also become instance methods on the
|
|
397
|
+
model:
|
|
398
|
+
|
|
399
|
+
```ruby
|
|
400
|
+
class Person < ApplicationRecord
|
|
401
|
+
has_enumeration_for :relationship_status, with: RelationshipStatus, create_helpers: true
|
|
402
|
+
end
|
|
403
|
+
|
|
404
|
+
person = Person.new(relationship_status: RelationshipStatus::DIVORCED)
|
|
405
|
+
person.ever_married? #=> true
|
|
406
|
+
```
|
|
407
|
+
|
|
408
|
+
The `prefix` option also applies to custom helpers:
|
|
409
|
+
|
|
410
|
+
```ruby
|
|
411
|
+
class Person < ApplicationRecord
|
|
412
|
+
has_enumeration_for :relationship_status,
|
|
413
|
+
with: RelationshipStatus, create_helpers: { prefix: true }
|
|
414
|
+
end
|
|
415
|
+
|
|
416
|
+
person = Person.new(relationship_status: RelationshipStatus::DIVORCED)
|
|
417
|
+
person.relationship_status_ever_married? #=> true
|
|
418
|
+
```
|
|
419
|
+
|
|
420
|
+
Custom helper methods return `nil` when the attribute is `nil`. If a method
|
|
421
|
+
name collides with an already-defined class method on the enumeration, an
|
|
422
|
+
`ArgumentError` is raised at load time.
|
|
423
|
+
|
|
338
424
|
- A scope method for each enumeration option if you pass the `create_scopes`
|
|
339
425
|
option as `true`:
|
|
340
426
|
|
|
@@ -344,7 +430,7 @@ This will create:
|
|
|
344
430
|
end
|
|
345
431
|
|
|
346
432
|
Person.married.to_sql
|
|
347
|
-
#=> SELECT "
|
|
433
|
+
#=> SELECT "people".* FROM "people" WHERE "people"."relationship_status" = "married"
|
|
348
434
|
```
|
|
349
435
|
|
|
350
436
|
The `:create_scopes` also accepts `prefix` option.
|
|
@@ -401,6 +487,12 @@ This will create:
|
|
|
401
487
|
#=> true
|
|
402
488
|
```
|
|
403
489
|
|
|
490
|
+
<!-- prettier-ignore -->
|
|
491
|
+
> [!NOTE]
|
|
492
|
+
> `skip_validation: true` disables all validations added by EnumerateIt,
|
|
493
|
+
> including the presence validation from `required: true`. If both are
|
|
494
|
+
> passed, `skip_validation` wins and `required` is silently ignored.
|
|
495
|
+
|
|
404
496
|
Remember that you can add validations to any kind of class and not only
|
|
405
497
|
`ActiveRecord` ones.
|
|
406
498
|
|
|
@@ -431,7 +523,7 @@ Yes,
|
|
|
431
523
|
|
|
432
524
|
## I18n
|
|
433
525
|
|
|
434
|
-
I18n lookup is provided for both `
|
|
526
|
+
I18n lookup is provided for both `_humanize` and `Enumeration#to_a` methods,
|
|
435
527
|
given the hash key is a Symbol. The I18n strings are located on
|
|
436
528
|
`enumerations.<enumeration_name>.<key>`:
|
|
437
529
|
|
|
@@ -453,11 +545,11 @@ end
|
|
|
453
545
|
|
|
454
546
|
p = Person.new
|
|
455
547
|
p.relationship_status = RelationshipStatus::MARRIED
|
|
456
|
-
p.relationship_status_humanize #
|
|
548
|
+
p.relationship_status_humanize # Key found in the locale file
|
|
457
549
|
#=> 'Casado'
|
|
458
550
|
|
|
459
551
|
p.relationship_status = RelationshipStatus::SINGLE
|
|
460
|
-
p.relationship_status_humanize #
|
|
552
|
+
p.relationship_status_humanize # Key missing, falls back to the humanized name
|
|
461
553
|
#=> 'Single'
|
|
462
554
|
```
|
|
463
555
|
|
|
@@ -550,12 +642,12 @@ you can see them on the [releases page](../../releases).
|
|
|
550
642
|
- Add tests for it. This is important so we don't break it in a future version
|
|
551
643
|
unintentionally.
|
|
552
644
|
- [Optional] Run the tests against a specific Gemfile:
|
|
553
|
-
`bundle exec appraisal rails_8.
|
|
645
|
+
`bundle exec appraisal rails_8.1 rake spec`.
|
|
554
646
|
- Run the tests against all supported versions: `bundle exec rake`
|
|
555
647
|
- Commit, but please do not mess with `Rakefile`, version, or history.
|
|
556
648
|
- Send a Pull Request. Bonus points for topic branches.
|
|
557
649
|
|
|
558
650
|
## Copyright
|
|
559
651
|
|
|
560
|
-
Copyright (c) 2010-
|
|
652
|
+
Copyright (c) 2010-2026 Cássio Marques and Lucas Caton. See `LICENSE` file for
|
|
561
653
|
details.
|
data/enumerate_it.gemspec
CHANGED
|
@@ -31,5 +31,5 @@ Gem::Specification.new do |gem|
|
|
|
31
31
|
gem.add_development_dependency 'rubocop'
|
|
32
32
|
gem.add_development_dependency 'rubocop-rake'
|
|
33
33
|
gem.add_development_dependency 'rubocop-rspec'
|
|
34
|
-
gem.add_development_dependency 'sqlite3'
|
|
34
|
+
gem.add_development_dependency 'sqlite3'
|
|
35
35
|
end
|
data/gemfiles/rails_7.0.gemfile
CHANGED
data/gemfiles/rails_7.1.gemfile
CHANGED
data/gemfiles/rails_7.2.gemfile
CHANGED
data/gemfiles/rails_8.0.gemfile
CHANGED
data/lib/enumerate_it/base.rb
CHANGED
|
@@ -51,8 +51,8 @@ module EnumerateIt
|
|
|
51
51
|
list.map { |value| t(value) }
|
|
52
52
|
end
|
|
53
53
|
|
|
54
|
-
def each_value(&)
|
|
55
|
-
list.each(&)
|
|
54
|
+
def each_value(&block)
|
|
55
|
+
list.each(&block)
|
|
56
56
|
end
|
|
57
57
|
|
|
58
58
|
def to_json(options = nil)
|
|
@@ -95,6 +95,25 @@ module EnumerateIt
|
|
|
95
95
|
I18n.t("enumerations.#{name.underscore}.#{value.to_s.underscore}", default: default)
|
|
96
96
|
end
|
|
97
97
|
|
|
98
|
+
def custom_helpers(&block)
|
|
99
|
+
@custom_helper_methods ||= []
|
|
100
|
+
|
|
101
|
+
mod = Module.new(&block)
|
|
102
|
+
methods = mod.instance_methods(false)
|
|
103
|
+
collisions = methods & singleton_class.instance_methods
|
|
104
|
+
|
|
105
|
+
raise ArgumentError, <<~MESSAGE.chomp if collisions.any?
|
|
106
|
+
Custom helper(s) '#{collisions.join(', ')}' would override existing EnumerateIt::Base methods
|
|
107
|
+
MESSAGE
|
|
108
|
+
|
|
109
|
+
@custom_helper_methods.concat(methods)
|
|
110
|
+
extend mod
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def custom_helper_methods
|
|
114
|
+
@custom_helper_methods || []
|
|
115
|
+
end
|
|
116
|
+
|
|
98
117
|
private
|
|
99
118
|
|
|
100
119
|
def sorted_map
|
|
@@ -134,9 +153,7 @@ module EnumerateIt
|
|
|
134
153
|
def values_hash(args)
|
|
135
154
|
return args.first if args.first.is_a?(Hash)
|
|
136
155
|
|
|
137
|
-
args.
|
|
138
|
-
hash[value] = value.to_s
|
|
139
|
-
end
|
|
156
|
+
args.to_h { |value| [value, value.to_s] }
|
|
140
157
|
end
|
|
141
158
|
end
|
|
142
159
|
end
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
module EnumerateIt
|
|
2
|
-
module ClassMethods
|
|
2
|
+
module ClassMethods # rubocop:disable Metrics/ModuleLength
|
|
3
3
|
def has_enumeration_for(attribute, options = {})
|
|
4
4
|
self.enumerations = enumerations.dup
|
|
5
5
|
|
|
@@ -17,7 +17,8 @@ module EnumerateIt
|
|
|
17
17
|
set_validations(attribute, options) unless options[:skip_validation]
|
|
18
18
|
|
|
19
19
|
if options[:create_helpers]
|
|
20
|
-
%w[create_helper_methods create_mutator_methods create_polymorphic_methods
|
|
20
|
+
%w[create_helper_methods create_mutator_methods create_polymorphic_methods
|
|
21
|
+
create_custom_helper_methods].each do |method|
|
|
21
22
|
send(method, options[:with], attribute, options[:create_helpers])
|
|
22
23
|
end
|
|
23
24
|
end
|
|
@@ -100,12 +101,27 @@ module EnumerateIt
|
|
|
100
101
|
end
|
|
101
102
|
end
|
|
102
103
|
|
|
104
|
+
def create_custom_helper_methods(klass, attribute_name, helpers)
|
|
105
|
+
return unless klass.custom_helper_methods.any?
|
|
106
|
+
|
|
107
|
+
prefix_name = "#{attribute_name}_" if helpers.is_a?(Hash) && helpers[:prefix]
|
|
108
|
+
|
|
109
|
+
class_eval do
|
|
110
|
+
klass.custom_helper_methods.each do |method_name|
|
|
111
|
+
define_method "#{prefix_name}#{method_name}" do
|
|
112
|
+
value = send(attribute_name)
|
|
113
|
+
klass.public_send(method_name, value) unless value.nil?
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
end
|
|
117
|
+
end
|
|
118
|
+
|
|
103
119
|
def define_enumeration_class(attribute, options)
|
|
104
120
|
return if options[:with]
|
|
105
121
|
|
|
106
122
|
inner_enum_class_name = attribute.to_s.camelize.to_sym
|
|
107
123
|
|
|
108
|
-
options[:with] = if
|
|
124
|
+
options[:with] = if const_defined?(inner_enum_class_name)
|
|
109
125
|
const_get(inner_enum_class_name)
|
|
110
126
|
else
|
|
111
127
|
attribute.to_s.camelize.constantize
|
data/lib/enumerate_it/version.rb
CHANGED
|
@@ -228,6 +228,55 @@ describe EnumerateIt::Base do
|
|
|
228
228
|
end
|
|
229
229
|
end
|
|
230
230
|
|
|
231
|
+
describe '.custom_helpers' do
|
|
232
|
+
context 'when methods are defined inside the block' do
|
|
233
|
+
it 'become class methods on the enum' do
|
|
234
|
+
expect(TestEnumerationWithCustomHelpers.lookup('1')).to eq(:one)
|
|
235
|
+
expect(TestEnumerationWithCustomHelpers.lookup('2')).to eq(:two)
|
|
236
|
+
expect(TestEnumerationWithCustomHelpers.boolean?('1')).to be(true)
|
|
237
|
+
expect(TestEnumerationWithCustomHelpers.boolean?('2')).to be(false)
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
context 'when a custom helper name collides with a built-in method' do
|
|
242
|
+
let(:build_colliding_enum) do
|
|
243
|
+
proc do
|
|
244
|
+
Class.new(EnumerateIt::Base) do
|
|
245
|
+
associate_values :collision
|
|
246
|
+
|
|
247
|
+
custom_helpers do
|
|
248
|
+
def list
|
|
249
|
+
'...'
|
|
250
|
+
end
|
|
251
|
+
end
|
|
252
|
+
end
|
|
253
|
+
end
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
it 'raises an ArgumentError' do
|
|
257
|
+
expect(&build_colliding_enum).to raise_error(
|
|
258
|
+
ArgumentError,
|
|
259
|
+
"Custom helper(s) 'list' would override existing EnumerateIt::Base methods"
|
|
260
|
+
)
|
|
261
|
+
end
|
|
262
|
+
end
|
|
263
|
+
end
|
|
264
|
+
|
|
265
|
+
describe '.custom_helper_methods' do
|
|
266
|
+
context 'when methods are defined inside custom_helpers block' do
|
|
267
|
+
it 'returns the registered names' do
|
|
268
|
+
expect(TestEnumerationWithCustomHelpers.custom_helper_methods)
|
|
269
|
+
.to eq(%i[lookup boolean?])
|
|
270
|
+
end
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
context 'when there is no .custom_helpers block on an enum' do
|
|
274
|
+
it 'returns an empty array' do
|
|
275
|
+
expect(TestEnumeration.custom_helper_methods).to eq([])
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
end
|
|
279
|
+
|
|
231
280
|
context 'associate values with a list' do
|
|
232
281
|
it 'creates constants for each enumeration value' do
|
|
233
282
|
expect(TestEnumerationWithList::FIRST).to eq('first')
|
|
@@ -289,11 +338,11 @@ describe EnumerateIt::Base do
|
|
|
289
338
|
attr_accessor :bla
|
|
290
339
|
|
|
291
340
|
class << self
|
|
292
|
-
def validates_inclusion_of(_attribute, _options)
|
|
341
|
+
def validates_inclusion_of(_attribute, _options) # rubocop:disable Naming/PredicateMethod
|
|
293
342
|
true
|
|
294
343
|
end
|
|
295
344
|
|
|
296
|
-
def validates_presence_of
|
|
345
|
+
def validates_presence_of # rubocop:disable Naming/PredicateMethod
|
|
297
346
|
true
|
|
298
347
|
end
|
|
299
348
|
end
|
data/spec/enumerate_it_spec.rb
CHANGED
|
@@ -4,6 +4,7 @@ describe EnumerateIt do
|
|
|
4
4
|
let :test_class do
|
|
5
5
|
Class.new do
|
|
6
6
|
extend EnumerateIt
|
|
7
|
+
|
|
7
8
|
attr_accessor :foobar
|
|
8
9
|
|
|
9
10
|
has_enumeration_for :foobar, with: TestEnumeration
|
|
@@ -41,6 +42,15 @@ describe EnumerateIt do
|
|
|
41
42
|
expect(target).not_to respond_to(:value_1?)
|
|
42
43
|
end
|
|
43
44
|
|
|
45
|
+
it 'defaults to not creating custom helper methods' do
|
|
46
|
+
klass = Class.new do
|
|
47
|
+
extend EnumerateIt
|
|
48
|
+
|
|
49
|
+
has_enumeration_for :foobar, with: TestEnumerationWithCustomHelpers
|
|
50
|
+
end
|
|
51
|
+
expect(klass.new).not_to respond_to(:lookup)
|
|
52
|
+
end
|
|
53
|
+
|
|
44
54
|
it 'stores the enumeration class in a class-level hash' do
|
|
45
55
|
expect(test_class.enumerations[:foobar]).to eq(TestEnumeration)
|
|
46
56
|
end
|
|
@@ -71,6 +81,7 @@ describe EnumerateIt do
|
|
|
71
81
|
let :test_class_for_enumeration_without_array do
|
|
72
82
|
Class.new do
|
|
73
83
|
extend EnumerateIt
|
|
84
|
+
|
|
74
85
|
attr_accessor :foobar
|
|
75
86
|
|
|
76
87
|
has_enumeration_for :foobar, with: TestEnumerationWithoutArray
|
|
@@ -102,6 +113,7 @@ describe EnumerateIt do
|
|
|
102
113
|
let :foo_bar_class do
|
|
103
114
|
Class.new do
|
|
104
115
|
extend EnumerateIt
|
|
116
|
+
|
|
105
117
|
attr_accessor :test_enumeration
|
|
106
118
|
|
|
107
119
|
has_enumeration_for :test_enumeration
|
|
@@ -124,12 +136,13 @@ describe EnumerateIt do
|
|
|
124
136
|
# rubocop:disable Lint/ConstantDefinitionInBlock
|
|
125
137
|
# rubocop:disable RSpec/LeakyConstantDeclaration
|
|
126
138
|
class NestedEnum < EnumerateIt::Base
|
|
127
|
-
associate_values foo: %w[1 Blerrgh], bar: ['2' => 'Blarghhh']
|
|
139
|
+
associate_values foo: %w[1 Blerrgh], bar: [{ '2' => 'Blarghhh' }]
|
|
128
140
|
end
|
|
129
141
|
# rubocop:enable RSpec/LeakyConstantDeclaration
|
|
130
142
|
# rubocop:enable Lint/ConstantDefinitionInBlock
|
|
131
143
|
|
|
132
144
|
extend EnumerateIt
|
|
145
|
+
|
|
133
146
|
attr_accessor :nested_enum
|
|
134
147
|
|
|
135
148
|
has_enumeration_for :nested_enum
|
|
@@ -151,6 +164,7 @@ describe EnumerateIt do
|
|
|
151
164
|
let :test_class_with_helper do
|
|
152
165
|
Class.new do
|
|
153
166
|
extend EnumerateIt
|
|
167
|
+
|
|
154
168
|
attr_accessor :foobar
|
|
155
169
|
|
|
156
170
|
has_enumeration_for :foobar, with: TestEnumeration, create_helpers: true
|
|
@@ -192,6 +206,7 @@ describe EnumerateIt do
|
|
|
192
206
|
let :test_class_with_prefixed_helper do
|
|
193
207
|
Class.new do
|
|
194
208
|
extend EnumerateIt
|
|
209
|
+
|
|
195
210
|
attr_accessor :foobar
|
|
196
211
|
|
|
197
212
|
has_enumeration_for :foobar, with: TestEnumeration, create_helpers: { prefix: true }
|
|
@@ -234,6 +249,7 @@ describe EnumerateIt do
|
|
|
234
249
|
let :polymorphic_class do
|
|
235
250
|
Class.new do
|
|
236
251
|
extend EnumerateIt
|
|
252
|
+
|
|
237
253
|
attr_accessor :foo
|
|
238
254
|
|
|
239
255
|
has_enumeration_for :foo, with: PolymorphicEnum, create_helpers: { polymorphic: true }
|
|
@@ -260,6 +276,7 @@ describe EnumerateIt do
|
|
|
260
276
|
let :polymorphic_class_with_suffix do
|
|
261
277
|
Class.new do
|
|
262
278
|
extend EnumerateIt
|
|
279
|
+
|
|
263
280
|
attr_accessor :foo
|
|
264
281
|
|
|
265
282
|
has_enumeration_for :foo, with: PolymorphicEnum,
|
|
@@ -280,6 +297,62 @@ describe EnumerateIt do
|
|
|
280
297
|
end
|
|
281
298
|
end
|
|
282
299
|
end
|
|
300
|
+
|
|
301
|
+
context 'with custom_helpers defined on the enumeration' do
|
|
302
|
+
context 'creates methods that delegates to the enum' do
|
|
303
|
+
let :test_class_with_custom_helpers do
|
|
304
|
+
Class.new do
|
|
305
|
+
extend EnumerateIt
|
|
306
|
+
|
|
307
|
+
attr_accessor :foobar
|
|
308
|
+
|
|
309
|
+
has_enumeration_for :foobar, with: TestEnumerationWithCustomHelpers,
|
|
310
|
+
create_helpers: true
|
|
311
|
+
|
|
312
|
+
def initialize(foobar)
|
|
313
|
+
@foobar = foobar
|
|
314
|
+
end
|
|
315
|
+
end
|
|
316
|
+
end
|
|
317
|
+
|
|
318
|
+
it 'returns value respective to attribute value' do
|
|
319
|
+
target = test_class_with_custom_helpers.new(TestEnumerationWithCustomHelpers::VALUE_ONE)
|
|
320
|
+
expect(target.lookup).to eq(:one)
|
|
321
|
+
expect(target.boolean?).to be(true)
|
|
322
|
+
end
|
|
323
|
+
|
|
324
|
+
it 'returns nil when attribute is nil' do
|
|
325
|
+
target = test_class_with_custom_helpers.new(nil)
|
|
326
|
+
expect(target.lookup).to be_nil
|
|
327
|
+
expect(target.boolean?).to be_nil
|
|
328
|
+
end
|
|
329
|
+
end
|
|
330
|
+
|
|
331
|
+
context 'create methods with prefix that delegates to the enum' do
|
|
332
|
+
let :test_class_with_prefixed_custom_helpers do
|
|
333
|
+
Class.new do
|
|
334
|
+
extend EnumerateIt
|
|
335
|
+
|
|
336
|
+
attr_accessor :foobar
|
|
337
|
+
|
|
338
|
+
has_enumeration_for :foobar, with: TestEnumerationWithCustomHelpers,
|
|
339
|
+
create_helpers: { prefix: true }
|
|
340
|
+
|
|
341
|
+
def initialize(foobar)
|
|
342
|
+
@foobar = foobar
|
|
343
|
+
end
|
|
344
|
+
end
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
it 'method is prefixed with the attribute name' do
|
|
348
|
+
target = test_class_with_prefixed_custom_helpers.new(TestEnumerationWithCustomHelpers::VALUE_ONE)
|
|
349
|
+
expect(target.foobar_lookup).to eq(:one)
|
|
350
|
+
expect(target.foobar_boolean?).to be(true)
|
|
351
|
+
expect(target).not_to respond_to(:lookup)
|
|
352
|
+
expect(target).not_to respond_to(:boolean?)
|
|
353
|
+
end
|
|
354
|
+
end
|
|
355
|
+
end
|
|
283
356
|
end
|
|
284
357
|
|
|
285
358
|
describe 'using the :create_scopes option' do
|
|
@@ -78,3 +78,17 @@ def create_enumeration_class_with_sort_mode(sort_mode)
|
|
|
78
78
|
)
|
|
79
79
|
end
|
|
80
80
|
end
|
|
81
|
+
|
|
82
|
+
class TestEnumerationWithCustomHelpers < EnumerateIt::Base
|
|
83
|
+
associate_values value_one: '1', value_two: '2'
|
|
84
|
+
|
|
85
|
+
custom_helpers do
|
|
86
|
+
def lookup(value)
|
|
87
|
+
{ '1' => :one, '2' => :two }[value]
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def boolean?(value)
|
|
91
|
+
value == '1'
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: enumerate_it
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 4.
|
|
4
|
+
version: 4.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Cássio Marques
|
|
@@ -154,16 +154,16 @@ dependencies:
|
|
|
154
154
|
name: sqlite3
|
|
155
155
|
requirement: !ruby/object:Gem::Requirement
|
|
156
156
|
requirements:
|
|
157
|
-
- - "
|
|
157
|
+
- - ">="
|
|
158
158
|
- !ruby/object:Gem::Version
|
|
159
|
-
version: '
|
|
159
|
+
version: '0'
|
|
160
160
|
type: :development
|
|
161
161
|
prerelease: false
|
|
162
162
|
version_requirements: !ruby/object:Gem::Requirement
|
|
163
163
|
requirements:
|
|
164
|
-
- - "
|
|
164
|
+
- - ">="
|
|
165
165
|
- !ruby/object:Gem::Version
|
|
166
|
-
version: '
|
|
166
|
+
version: '0'
|
|
167
167
|
description: Enumerations for Ruby with some magic powers!
|
|
168
168
|
executables: []
|
|
169
169
|
extensions: []
|
|
@@ -172,6 +172,7 @@ files:
|
|
|
172
172
|
- ".github/dependabot.yml"
|
|
173
173
|
- ".github/workflows/ci.yml"
|
|
174
174
|
- ".gitignore"
|
|
175
|
+
- ".prettierrc.json"
|
|
175
176
|
- ".rspec"
|
|
176
177
|
- ".rubocop.yml"
|
|
177
178
|
- Appraisals
|
|
@@ -188,6 +189,7 @@ files:
|
|
|
188
189
|
- gemfiles/rails_7.1.gemfile
|
|
189
190
|
- gemfiles/rails_7.2.gemfile
|
|
190
191
|
- gemfiles/rails_8.0.gemfile
|
|
192
|
+
- gemfiles/rails_8.1.gemfile
|
|
191
193
|
- lib/enumerate_it.rb
|
|
192
194
|
- lib/enumerate_it/base.rb
|
|
193
195
|
- lib/enumerate_it/class_methods.rb
|
|
@@ -223,7 +225,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
223
225
|
- !ruby/object:Gem::Version
|
|
224
226
|
version: '0'
|
|
225
227
|
requirements: []
|
|
226
|
-
rubygems_version:
|
|
228
|
+
rubygems_version: 4.0.3
|
|
227
229
|
specification_version: 4
|
|
228
230
|
summary: Ruby Enumerations
|
|
229
231
|
test_files: []
|