enumbler 0.4.1 → 0.6.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/Gemfile.lock +17 -17
- data/README.md +39 -9
- data/enumbler.gemspec +2 -2
- data/lib/enumbler.rb +5 -0
- data/lib/enumbler/collection.rb +24 -0
- data/lib/enumbler/enabler.rb +164 -40
- data/lib/enumbler/enumble.rb +26 -5
- data/lib/enumbler/version.rb +1 -1
- metadata +23 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b196f7e09065d7f461c8f0c4ae87e25d849600dfa38840b2aba5b9f2d75c2d7b
|
4
|
+
data.tar.gz: f187980e2ba0a7b79dc9657c1469e205aa1e3efb7439190d2d5592d5df0851b9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 43c6e81c18303961b9e1ea530282f70fff80d76b57bf57eeef347f014a3bc6918d525748a0e0ea216bd4aed31579b9c133d43dd085a0cca42dbab4c19ab5f839
|
7
|
+
data.tar.gz: 96635852aa098120cc7a93e30d8e51c865e0be220ae73b93f06cca1af783feaa9776cb2295d02f5a3cfbc4abff6c2d1495c0b4951c9b06755f444a2db3cc931d
|
data/Gemfile.lock
CHANGED
@@ -1,27 +1,27 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
enumbler (0.
|
5
|
-
activerecord (
|
6
|
-
activesupport (
|
4
|
+
enumbler (0.6.1)
|
5
|
+
activerecord (>= 5.2.3, < 6.1)
|
6
|
+
activesupport (>= 5.2.3, < 6.1)
|
7
7
|
|
8
8
|
GEM
|
9
9
|
remote: https://rubygems.org/
|
10
10
|
specs:
|
11
|
-
activemodel (6.0.
|
12
|
-
activesupport (= 6.0.
|
13
|
-
activerecord (6.0.
|
14
|
-
activemodel (= 6.0.
|
15
|
-
activesupport (= 6.0.
|
16
|
-
activesupport (6.0.
|
11
|
+
activemodel (6.0.3.1)
|
12
|
+
activesupport (= 6.0.3.1)
|
13
|
+
activerecord (6.0.3.1)
|
14
|
+
activemodel (= 6.0.3.1)
|
15
|
+
activesupport (= 6.0.3.1)
|
16
|
+
activesupport (6.0.3.1)
|
17
17
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
18
18
|
i18n (>= 0.7, < 2)
|
19
19
|
minitest (~> 5.1)
|
20
20
|
tzinfo (~> 1.1)
|
21
|
-
zeitwerk (~> 2.2)
|
21
|
+
zeitwerk (~> 2.2, >= 2.2.2)
|
22
22
|
ast (2.4.0)
|
23
23
|
concurrent-ruby (1.1.6)
|
24
|
-
database_cleaner (1.8.
|
24
|
+
database_cleaner (1.8.5)
|
25
25
|
database_cleaner-active_record (1.8.0)
|
26
26
|
activerecord
|
27
27
|
database_cleaner (~> 1.8.0)
|
@@ -32,9 +32,9 @@ GEM
|
|
32
32
|
i18n (1.8.2)
|
33
33
|
concurrent-ruby (~> 1.0)
|
34
34
|
jaro_winkler (1.5.4)
|
35
|
-
minitest (5.14.
|
35
|
+
minitest (5.14.1)
|
36
36
|
parallel (1.19.1)
|
37
|
-
parser (2.7.1.
|
37
|
+
parser (2.7.1.3)
|
38
38
|
ast (~> 2.4.0)
|
39
39
|
rainbow (3.0.0)
|
40
40
|
rake (12.3.3)
|
@@ -43,15 +43,15 @@ GEM
|
|
43
43
|
rspec-core (~> 3.9.0)
|
44
44
|
rspec-expectations (~> 3.9.0)
|
45
45
|
rspec-mocks (~> 3.9.0)
|
46
|
-
rspec-core (3.9.
|
47
|
-
rspec-support (~> 3.9.
|
48
|
-
rspec-expectations (3.9.
|
46
|
+
rspec-core (3.9.2)
|
47
|
+
rspec-support (~> 3.9.3)
|
48
|
+
rspec-expectations (3.9.2)
|
49
49
|
diff-lcs (>= 1.2.0, < 2.0)
|
50
50
|
rspec-support (~> 3.9.0)
|
51
51
|
rspec-mocks (3.9.1)
|
52
52
|
diff-lcs (>= 1.2.0, < 2.0)
|
53
53
|
rspec-support (~> 3.9.0)
|
54
|
-
rspec-support (3.9.
|
54
|
+
rspec-support (3.9.3)
|
55
55
|
rubocop (0.81.0)
|
56
56
|
jaro_winkler (~> 1.5.1)
|
57
57
|
parallel (~> 1.10)
|
data/README.md
CHANGED
@@ -26,6 +26,7 @@ Suppose you have a `House` and you want to add some `colors` to the house. You
|
|
26
26
|
ActiveRecord::Schema.define do
|
27
27
|
create_table :colors|t|
|
28
28
|
t.string :label, null: false, index: { unique: true }
|
29
|
+
t.string :hex, null: true
|
29
30
|
end
|
30
31
|
|
31
32
|
create_table :houses|t|
|
@@ -42,8 +43,8 @@ end
|
|
42
43
|
class Color < ApplicationRecord
|
43
44
|
include Enumbler::Enabler
|
44
45
|
|
45
|
-
enumble :black, 1
|
46
|
-
enumble :white, 2
|
46
|
+
enumble :black, 1, hex: '000000'
|
47
|
+
enumble :white, 2, hex: 'ffffff'
|
47
48
|
enumble :dark_brown, 3
|
48
49
|
enumble :infinity, 4, label: 'Infinity - and beyond!'
|
49
50
|
end
|
@@ -54,17 +55,45 @@ class House < ApplicationRecord
|
|
54
55
|
end
|
55
56
|
|
56
57
|
# This gives you some power:
|
57
|
-
Color::BLACK
|
58
|
-
Color.black
|
59
|
-
Color.black.black?
|
60
|
-
Color.black.is_black
|
61
|
-
Color.white.not_black?
|
58
|
+
Color::BLACK # => 1
|
59
|
+
Color.black # => equivalent to Color.find(1)
|
60
|
+
Color.black.black? # => true
|
61
|
+
Color.black.is_black # => true
|
62
|
+
Color.white.not_black? # => true
|
63
|
+
|
64
|
+
# Get attributes without hitting the database
|
65
|
+
Color.black(:id) # => 1
|
66
|
+
Color.black(:enum) # => :black
|
67
|
+
Color.black(:label) # => 'black'
|
68
|
+
Color.black(:graphql_enum) # => 'BLACK'
|
69
|
+
|
70
|
+
# Get an Enumble object from an id, label, enum, or ActiveRecord model
|
71
|
+
Color.find_enumbles(:black, 'white') # => [Enumbler::Enumble<:black>, Enumbler::Enumble<:white>]
|
72
|
+
Color.find_enumbles(:black, 'does-not-exist') # => [Enumbler::Enumble<:black>, nil]
|
73
|
+
|
74
|
+
Color.find_enumble(:black) # => Enumbler::Enumble<:black>
|
75
|
+
|
76
|
+
# raises errors if none found
|
77
|
+
Color.find_enumbles!!(:black, 'does-no-exist') # => raises Enumbler::Error
|
78
|
+
Color.find_enumble!(:does_not_exist) # => raises Enumbler::Error
|
79
|
+
|
80
|
+
# Get ids flexibly, without raising an error if none found
|
81
|
+
Color.ids_from_enumbler(:black, 'white') # => [1, 2]
|
82
|
+
Color.ids_from_enumbler(:black, 'does-no-exist') # => [1, nil]
|
83
|
+
|
84
|
+
# Raise an error if none found
|
85
|
+
Color.ids_from_enumbler!(:black, 'does-no-exist') # => raises Enumbler::Error
|
86
|
+
Color.id_from_enumbler!(:does_not_exist) # => raises Enumbler::Error
|
87
|
+
|
88
|
+
# Get enumble object by id
|
62
89
|
|
63
90
|
house = House.create!(color: Color.black)
|
64
91
|
house.black?
|
65
92
|
house.not_black?
|
66
93
|
|
67
|
-
House.color
|
94
|
+
house2 = House.create!(color: Color.white)
|
95
|
+
House.color(:black, :white) # => ActiveRecord::Relation<house, house2>
|
96
|
+
House.color(Color.black, :white) # => ActiveRecord::Relation<house, house2>
|
68
97
|
```
|
69
98
|
|
70
99
|
### Use a column other than `label`
|
@@ -98,7 +127,8 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
|
|
98
127
|
|
99
128
|
## Roadmap
|
100
129
|
|
101
|
-
|
130
|
+
* We need to add in support for additional attributes/columns in the enumbled table. For example, following the `Color` concept, we may want to have a column which is `hex` and stores the colors `hex` value (e.g., `FFFFFF`). This should be supported.
|
131
|
+
* Ideally, we could make this work more like a traditional `enum`; for example, overriding the `.where` method by allowing something like: `House.where(color: :blue)` instead of `House.where_color(:blue)`. But right now am in a rush and not sure how to go about doing that properly.
|
102
132
|
|
103
133
|
## Contributing
|
104
134
|
|
data/enumbler.gemspec
CHANGED
@@ -29,8 +29,8 @@ Gem::Specification.new do |spec|
|
|
29
29
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
30
30
|
spec.require_paths = ['lib']
|
31
31
|
|
32
|
-
spec.add_dependency 'activerecord', '
|
33
|
-
spec.add_dependency 'activesupport', '
|
32
|
+
spec.add_dependency 'activerecord', ['>= 5.2.3', '< 6.1']
|
33
|
+
spec.add_dependency 'activesupport', ['>= 5.2.3', '< 6.1']
|
34
34
|
|
35
35
|
spec.add_development_dependency 'database_cleaner-active_record', '~> 1.8.0'
|
36
36
|
spec.add_development_dependency 'fuubar', '~> 2.5'
|
data/lib/enumbler.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require 'enumbler/collection'
|
3
4
|
require 'enumbler/enumble'
|
4
5
|
require 'enumbler/enabler'
|
5
6
|
require 'enumbler/version'
|
@@ -85,6 +86,10 @@ module Enumbler
|
|
85
86
|
where(column_name => enumbled_model.ids_from_enumbler(args))
|
86
87
|
end
|
87
88
|
|
89
|
+
define_singleton_method("#{cmethod}!") do |*args|
|
90
|
+
where(column_name => enumbled_model.ids_from_enumbler!(args))
|
91
|
+
end
|
92
|
+
|
88
93
|
enumbled_model.enumbles.each do |enumble|
|
89
94
|
method_name = prefix ? "#{model_name}_#{enumble.enum}?" : "#{enumble.enum}?"
|
90
95
|
not_method_name = prefix ? "#{model_name}_not_#{enumble.enum}?" : "not_#{enumble.enum}?"
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Enumbler
|
4
|
+
# Not sure if this will be needed but was leaning toward a custom wrapper for
|
5
|
+
# our array holding the `enumbles` for our model. As it is, allows you to
|
6
|
+
# query them based on the enum:
|
7
|
+
#
|
8
|
+
# ```
|
9
|
+
# Color.enumbles.black # => [Enumbler::Enumble]
|
10
|
+
# ```
|
11
|
+
class Collection < Array
|
12
|
+
def method_missing(method_name, *args, &block)
|
13
|
+
enumble = find { |e| e.enum == method_name }
|
14
|
+
return enumble if enumble.present?
|
15
|
+
|
16
|
+
super
|
17
|
+
end
|
18
|
+
|
19
|
+
def respond_to_missing?(method_name, include_private = false)
|
20
|
+
enumble = find { |e| e.enum == method_name }
|
21
|
+
enumble.present? || super
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
data/lib/enumbler/enabler.rb
CHANGED
@@ -40,8 +40,8 @@ module Enumbler
|
|
40
40
|
# class Color < ApplicationRecord
|
41
41
|
# include Enumbler::Enabler
|
42
42
|
#
|
43
|
-
# enumble :black, 1
|
44
|
-
# enumble :white, 2
|
43
|
+
# enumble :black, 1, hex: '000000'
|
44
|
+
# enumble :white, 2, hex: 'ffffff'
|
45
45
|
# enumble :dark_brown, 3, # label: 'dark-brown'
|
46
46
|
# enumble :black_hole, 3, label: 'Oh my! It is a black hole!'
|
47
47
|
# end
|
@@ -55,20 +55,22 @@ module Enumbler
|
|
55
55
|
# @param enum [Symbol] the enum representation
|
56
56
|
# @param id [Integer] the primary key value
|
57
57
|
# @param label [String] optional: label for humans
|
58
|
-
# @param **
|
58
|
+
# @param **attributes [Hash] optional: additional attributes and values that
|
59
59
|
# will be saved to the database for this enumble record
|
60
|
-
def enumble(enum, id, label: nil, **
|
61
|
-
@enumbles ||=
|
60
|
+
def enumble(enum, id, label: nil, **attributes)
|
61
|
+
@enumbles ||= Enumbler::Collection.new
|
62
62
|
@enumbled_model = self
|
63
63
|
@enumbler_label_column_name ||= :label
|
64
64
|
|
65
|
-
|
65
|
+
raise_error_if_model_does_not_support_attributes(attributes)
|
66
|
+
|
67
|
+
enumble = Enumble.new(enum, id, label: label, label_column_name: @enumbler_label_column_name, **attributes)
|
66
68
|
|
67
69
|
if @enumbles.include?(enumble)
|
68
70
|
raise Error, "You cannot add the same Enumble twice! Attempted to add: #{enum}, #{id}."
|
69
71
|
end
|
70
72
|
|
71
|
-
define_dynamic_methods_and_constants_for_enumbled_model(
|
73
|
+
define_dynamic_methods_and_constants_for_enumbled_model(enumble)
|
72
74
|
|
73
75
|
@enumbles << enumble
|
74
76
|
end
|
@@ -97,6 +99,93 @@ module Enumbler
|
|
97
99
|
@enumbler_label_column_name = label_column_name
|
98
100
|
end
|
99
101
|
|
102
|
+
# See {.find_enumbles}. Simply returns the first object. Use when you
|
103
|
+
# want one argument to be found and not returned in an array.
|
104
|
+
# @raise [Error] when there is no [Enumbler::Enumble] to be found and
|
105
|
+
# `raise_error: true`
|
106
|
+
# @param args [Integer, String, Symbol]
|
107
|
+
# @param case_sensitive [Boolean] should a String search be case sensitive
|
108
|
+
# (default: false)
|
109
|
+
# @param raise_error [Boolean] raise an error if not found (default:
|
110
|
+
# false)
|
111
|
+
# @return [Enumbler::Enumble]
|
112
|
+
def find_enumble(arg, case_sensitive: false, raise_error: false)
|
113
|
+
find_enumbles(arg, case_sensitive: case_sensitive, raise_error: raise_error).first
|
114
|
+
end
|
115
|
+
|
116
|
+
# See {.find_enumbles}. Simply returns the first object. Use when you
|
117
|
+
# want one argument to be found and not returned in an array. Raises error
|
118
|
+
# if none found.
|
119
|
+
# @raise [Error] when there is no [Enumbler::Enumble] to be found and
|
120
|
+
# `raise_error: true`
|
121
|
+
# @param args [Integer, String, Symbol]
|
122
|
+
# @param case_sensitive [Boolean] should a String search be case sensitive
|
123
|
+
# (default: false)
|
124
|
+
# @return [Enumbler::Enumble]
|
125
|
+
def find_enumble!(arg, case_sensitive: false)
|
126
|
+
find_enumbles(arg, case_sensitive: case_sensitive, raise_error: true).first
|
127
|
+
end
|
128
|
+
|
129
|
+
# Finds an array of {Enumbler::Enumble} objects matching the given
|
130
|
+
# argument. Accepts an Integer, String, Symbol, or ActiveRecord instance.
|
131
|
+
#
|
132
|
+
# This method is designed to let you get information about the record
|
133
|
+
# without having to hit the database. Returns `nil` when none found
|
134
|
+
# unless `raise_error` is `true`.
|
135
|
+
#
|
136
|
+
# Color.find_enumbles(:black, 'white', 'not-found')
|
137
|
+
# #=> [Enumbler::Enumble<:black>, Enumbler::Enumble<:white>, nil]
|
138
|
+
#
|
139
|
+
# @raise [Error] when there is no [Enumbler::Enumble] to be found and
|
140
|
+
# `raise_error: true`
|
141
|
+
# @param args [Integer, String, Symbol]
|
142
|
+
# @param case_sensitive [Boolean] should a String search be case sensitive
|
143
|
+
# (default: false)
|
144
|
+
# @param raise_error [Boolean] raise an error if not found (default:
|
145
|
+
# false)
|
146
|
+
# @return [Array<Enumbler::Enumble>]
|
147
|
+
def find_enumbles(*args, case_sensitive: false, raise_error: false)
|
148
|
+
args.flatten.compact.uniq.map do |arg|
|
149
|
+
err = "Unable to find a #{@enumbled_model}#enumble with #{arg}"
|
150
|
+
|
151
|
+
begin
|
152
|
+
arg = Integer(arg) # raises Type error if not a real integer
|
153
|
+
enumble = @enumbled_model.enumbles.find { |e| e.id == arg }
|
154
|
+
rescue TypeError, ArgumentError
|
155
|
+
enumble =
|
156
|
+
if arg.is_a?(Symbol)
|
157
|
+
@enumbled_model.enumbles.find { |e| e.enum == arg }
|
158
|
+
elsif arg.is_a?(String)
|
159
|
+
@enumbled_model.enumbles.find do |e|
|
160
|
+
case_sensitive ? e.label == arg : arg.casecmp?(e.label)
|
161
|
+
end
|
162
|
+
elsif arg.instance_of?(@enumbled_model)
|
163
|
+
arg.enumble
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
if enumble.present?
|
168
|
+
enumble
|
169
|
+
else
|
170
|
+
raise Error if raise_error
|
171
|
+
|
172
|
+
nil
|
173
|
+
end
|
174
|
+
rescue Error
|
175
|
+
raise Error, err
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
# See {.find_enumbles}. Same method, only raises error when none found.
|
180
|
+
# @raise [Error] when there is no [Enumbler::Enumble] to be found
|
181
|
+
# @param args [Integer, String, Symbol]
|
182
|
+
# @param case_sensitive [Boolean] should a String search be case sensitive
|
183
|
+
# (default: false)
|
184
|
+
# @return [Array<Enumbler::Enumble>]
|
185
|
+
def find_enumbles!(*args, case_sensitive: false)
|
186
|
+
find_enumbles(*args, case_sensitive: case_sensitive, raise_error: true)
|
187
|
+
end
|
188
|
+
|
100
189
|
# Return the record id for a given argument. Can accept an Integer, a
|
101
190
|
# Symbol, or an instance of Enumbled model. This lookup is a database-free
|
102
191
|
# lookup.
|
@@ -107,9 +196,25 @@ module Enumbler
|
|
107
196
|
#
|
108
197
|
# @raise [Error] when there is no enumble to be found
|
109
198
|
# @param arg [Integer, Symbol, Class]
|
199
|
+
# @param case_sensitive [Boolean] should a string search be performed with
|
200
|
+
# case sensitivity (default: false)
|
201
|
+
# @param raise_error [Boolean] raise an error if not found (default:
|
202
|
+
# false)
|
110
203
|
# @return [Integer]
|
111
|
-
def id_from_enumbler(arg)
|
112
|
-
ids_from_enumbler(arg).first
|
204
|
+
def id_from_enumbler(arg, case_sensitive: false, raise_error: false)
|
205
|
+
ids_from_enumbler(arg, case_sensitive: case_sensitive, raise_error: raise_error).first
|
206
|
+
end
|
207
|
+
|
208
|
+
# See {.ids_from_enumbler}. Raises error if none found.
|
209
|
+
# @raise [Error] when there is no enumble to be found
|
210
|
+
# @param arg [Integer, Symbol, Class]
|
211
|
+
# @param case_sensitive [Boolean] should a string search be performed with
|
212
|
+
# case sensitivity (default: false)
|
213
|
+
# @param raise_error [Boolean] raise an error if not found (default:
|
214
|
+
# false)
|
215
|
+
# @return [Integer]
|
216
|
+
def id_from_enumbler!(arg, case_sensitive: false)
|
217
|
+
ids_from_enumbler(arg, case_sensitive: case_sensitive, raise_error: true).first
|
113
218
|
end
|
114
219
|
|
115
220
|
# Return the record id(s) based on different argument types. Can accept
|
@@ -118,38 +223,39 @@ module Enumbler
|
|
118
223
|
#
|
119
224
|
# Color.ids_from_enumbler(1, 2) # => [1, 2]
|
120
225
|
# Color.ids_from_enumbler(:black, :white) # => [1, 2]
|
226
|
+
# Color.ids_from_enumbler('black', :white) # => [1, 2]
|
121
227
|
# Color.ids_from_enumbler(Color.black, Color.white) # => [1, 2]
|
122
228
|
#
|
123
229
|
# @raise [Error] when there is no enumble to be found
|
124
230
|
# @param *args [Integer, Symbol, Class]
|
231
|
+
# @param case_sensitive [Boolean] should a string search be performed with
|
232
|
+
# case sensitivity (default: false)
|
233
|
+
# @param raise_error [Boolean] raise an error if not found (default:
|
234
|
+
# false)
|
125
235
|
# @return [Array<Integer>]
|
126
|
-
def ids_from_enumbler(*args)
|
127
|
-
args
|
128
|
-
|
129
|
-
|
130
|
-
begin
|
131
|
-
arg = Integer(arg) # raises Type error if not a real integer
|
132
|
-
enumble = @enumbled_model.enumbles.find { |e| e.id == arg }
|
133
|
-
rescue TypeError
|
134
|
-
enumble = if arg.is_a?(Symbol)
|
135
|
-
@enumbled_model.enumbles.find { |e| e.enum == arg }
|
136
|
-
elsif arg.instance_of?(@enumbled_model)
|
137
|
-
arg.enumble
|
138
|
-
end
|
139
|
-
end
|
236
|
+
def ids_from_enumbler(*args, case_sensitive: false, raise_error: false)
|
237
|
+
enumbles = find_enumbles(*args, case_sensitive: case_sensitive, raise_error: raise_error)
|
238
|
+
enumbles.map { |e| e&.id }
|
239
|
+
end
|
140
240
|
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
241
|
+
# See {.ids_from_enumbler}. Raises error when none found.
|
242
|
+
# @raise [Error] when there is no enumble to be found
|
243
|
+
# @param *args [Integer, Symbol, Class]
|
244
|
+
# @param case_sensitive [Boolean] should a string search be performed with
|
245
|
+
# case sensitivity (default: false)
|
246
|
+
# @return [Array<Integer>]
|
247
|
+
def ids_from_enumbler!(*args, case_sensitive: false)
|
248
|
+
enumbles = find_enumbles!(*args, case_sensitive: case_sensitive)
|
249
|
+
enumbles.map(&:id)
|
145
250
|
end
|
146
251
|
|
147
252
|
# Seeds the database with the Enumbler data.
|
148
253
|
# @param delete_missing_records [Boolean] remove any records that are no
|
149
254
|
# longer defined (default: false)
|
150
|
-
|
255
|
+
# @param validate [Boolean] validate on save?
|
256
|
+
def seed_the_enumbler(delete_missing_records: false, validate: true)
|
151
257
|
max_database_id = all.order('id desc').take&.id || 0
|
152
|
-
max_enumble_id = enumbles.map(&:id).max
|
258
|
+
max_enumble_id = @enumbles.map(&:id).max
|
153
259
|
|
154
260
|
# If we are not deleting records, we just need to update each listed
|
155
261
|
# enumble and skip anything else in the database. If we are deleting
|
@@ -174,7 +280,7 @@ module Enumbler
|
|
174
280
|
|
175
281
|
record = find_or_initialize_by(id: id)
|
176
282
|
record.attributes = enumble.attributes
|
177
|
-
record.save!
|
283
|
+
record.save!(validate: validate)
|
178
284
|
end
|
179
285
|
|
180
286
|
where(id: discarded_ids).delete_all if delete_missing_records
|
@@ -182,22 +288,40 @@ module Enumbler
|
|
182
288
|
|
183
289
|
# Seeds the database with the Enumble data, removing any records that are no
|
184
290
|
# longer defined.
|
185
|
-
|
186
|
-
|
291
|
+
# @param validate [Boolean] validate on save?
|
292
|
+
def seed_the_enumbler!(validate: true)
|
293
|
+
seed_the_enumbler(delete_missing_records: true, validate: validate)
|
187
294
|
end
|
188
295
|
|
189
296
|
private
|
190
297
|
|
191
|
-
def define_dynamic_methods_and_constants_for_enumbled_model(
|
192
|
-
method_name = "#{enum}?"
|
193
|
-
not_method_name = "not_#{enum}?"
|
194
|
-
alias_method_name = "is_#{enum}"
|
298
|
+
def define_dynamic_methods_and_constants_for_enumbled_model(enumble)
|
299
|
+
method_name = "#{enumble.enum}?"
|
300
|
+
not_method_name = "not_#{enumble.enum}?"
|
301
|
+
alias_method_name = "is_#{enumble.enum}"
|
195
302
|
|
196
|
-
const_set(enum.to_s.upcase, id)
|
197
|
-
define_method(method_name) {
|
198
|
-
define_method(not_method_name) {
|
303
|
+
const_set(enumble.enum.to_s.upcase, enumble.id)
|
304
|
+
define_method(method_name) { id == enumble.id }
|
305
|
+
define_method(not_method_name) { id != enumble.id }
|
199
306
|
alias_method alias_method_name, method_name
|
200
|
-
define_singleton_method(enum)
|
307
|
+
define_singleton_method(enumble.enum) do |attr = nil|
|
308
|
+
return find(enumble.id) if attr.nil?
|
309
|
+
|
310
|
+
enumble.send(attr)
|
311
|
+
rescue NoMethodError
|
312
|
+
raise Enumbler::Error, "The attribute #{attr} is not supported on this Enumble."
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
def raise_error_if_model_does_not_support_attributes(attributes)
|
317
|
+
return if attributes.blank?
|
318
|
+
|
319
|
+
unsupported_attrs = attributes.reject { |key, _value| has_attribute?(key) }
|
320
|
+
|
321
|
+
return if unsupported_attrs.blank?
|
322
|
+
|
323
|
+
raise Enumbler::Error,
|
324
|
+
"The model #{self} does not support the attribute(s): #{unsupported_attrs.keys.map(&:to_s).to_sentence}"
|
201
325
|
end
|
202
326
|
end
|
203
327
|
end
|
data/lib/enumbler/enumble.rb
CHANGED
@@ -3,14 +3,14 @@
|
|
3
3
|
module Enumbler
|
4
4
|
# Class that holds each row of Enumble data.
|
5
5
|
class Enumble
|
6
|
-
attr_reader :id, :enum, :label, :label_column_name
|
6
|
+
attr_reader :id, :enum, :label, :label_column_name
|
7
7
|
|
8
|
-
def initialize(enum, id, label: nil, label_column_name: :label, **
|
8
|
+
def initialize(enum, id, label: nil, label_column_name: :label, **attributes)
|
9
9
|
@id = id
|
10
10
|
@enum = enum
|
11
11
|
@label = label || enum.to_s.dasherize
|
12
12
|
@label_column_name = label_column_name
|
13
|
-
@
|
13
|
+
@additional_attributes = attributes || {}
|
14
14
|
end
|
15
15
|
|
16
16
|
def ==(other)
|
@@ -19,15 +19,36 @@ module Enumbler
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def attributes
|
22
|
-
{
|
22
|
+
@additional_attributes.merge({
|
23
23
|
id: id,
|
24
24
|
label_column_name => label,
|
25
|
-
}
|
25
|
+
})
|
26
|
+
end
|
27
|
+
|
28
|
+
# Used to return itself from a class method.
|
29
|
+
#
|
30
|
+
# ```
|
31
|
+
# Color.black(:enumble) #=> <Enumble:0x00007fb4396a78c8>
|
32
|
+
# ```
|
33
|
+
# @return [Enumbler::Enumble]
|
34
|
+
def enumble
|
35
|
+
self
|
26
36
|
end
|
27
37
|
|
28
38
|
def eql?(other)
|
29
39
|
other.class == self.class &&
|
30
40
|
(other.id == id || other.enum == enum || other.label == label)
|
31
41
|
end
|
42
|
+
|
43
|
+
# Standardizing the enum for a GraphQL schema with an uppercase string
|
44
|
+
# value.
|
45
|
+
# @return [String]
|
46
|
+
def graphql_enum
|
47
|
+
enum.to_s.upcase
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_s
|
51
|
+
enum
|
52
|
+
end
|
32
53
|
end
|
33
54
|
end
|
data/lib/enumbler/version.rb
CHANGED
metadata
CHANGED
@@ -1,43 +1,55 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: enumbler
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Damon Timm
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-07-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 5.2.3
|
20
|
+
- - "<"
|
18
21
|
- !ruby/object:Gem::Version
|
19
|
-
version: 6.
|
22
|
+
version: '6.1'
|
20
23
|
type: :runtime
|
21
24
|
prerelease: false
|
22
25
|
version_requirements: !ruby/object:Gem::Requirement
|
23
26
|
requirements:
|
24
|
-
- - "
|
27
|
+
- - ">="
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: 5.2.3
|
30
|
+
- - "<"
|
25
31
|
- !ruby/object:Gem::Version
|
26
|
-
version: 6.
|
32
|
+
version: '6.1'
|
27
33
|
- !ruby/object:Gem::Dependency
|
28
34
|
name: activesupport
|
29
35
|
requirement: !ruby/object:Gem::Requirement
|
30
36
|
requirements:
|
31
|
-
- - "
|
37
|
+
- - ">="
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: 5.2.3
|
40
|
+
- - "<"
|
32
41
|
- !ruby/object:Gem::Version
|
33
|
-
version: 6.
|
42
|
+
version: '6.1'
|
34
43
|
type: :runtime
|
35
44
|
prerelease: false
|
36
45
|
version_requirements: !ruby/object:Gem::Requirement
|
37
46
|
requirements:
|
38
|
-
- - "
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 5.2.3
|
50
|
+
- - "<"
|
39
51
|
- !ruby/object:Gem::Version
|
40
|
-
version: 6.
|
52
|
+
version: '6.1'
|
41
53
|
- !ruby/object:Gem::Dependency
|
42
54
|
name: database_cleaner-active_record
|
43
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -144,6 +156,7 @@ files:
|
|
144
156
|
- bin/setup
|
145
157
|
- enumbler.gemspec
|
146
158
|
- lib/enumbler.rb
|
159
|
+
- lib/enumbler/collection.rb
|
147
160
|
- lib/enumbler/enabler.rb
|
148
161
|
- lib/enumbler/enumble.rb
|
149
162
|
- lib/enumbler/version.rb
|