enum_ext 0.4.6 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +24 -0
- data/README.md +94 -68
- data/lib/enum_ext/version.rb +1 -1
- data/lib/enum_ext.rb +120 -48
- 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: e43e1644acff1729643340c16a085e015c66a76949a313fe3d95c229261fe165
|
4
|
+
data.tar.gz: a5ccf00bf5bdc65d3e26d0d115e52dad86afe41cab4e71c5758ee43cbf9ff31f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d521069cf6f12ee8ed5117a3a521fdc6f4c7e5e7e798a8fea32efaa28ebe549bf23c6e939f15ff0857b193a3162bfa386e8b5784e3f9b69fdabf861a22701a99
|
7
|
+
data.tar.gz: 263fe623bce43c3f1da806ef0904d36494918f1d168c77a1197e181337bd0d88cf51e30a0850b501d42156402a0131aa10ba5688026b5e1d09e7633bb2b1610c
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,27 @@
|
|
1
|
+
# 0.5.0
|
2
|
+
* with/without definitions will go standalone now, you need explicitly address them. Ex:
|
3
|
+
```
|
4
|
+
multi_enum_scopes :test_type
|
5
|
+
# OR
|
6
|
+
enum test_type: [..], ext: [:multi_enum_scopes]
|
7
|
+
```
|
8
|
+
* easier supersets definitions, no raw level class methods and multiple method call needed anymore for additive supersets:
|
9
|
+
|
10
|
+
```ruby
|
11
|
+
ext_enum_sets :test_type, raw_level: [:unit_test, :spec]
|
12
|
+
ext_enum_sets :test_type,
|
13
|
+
fast: raw_level_test_types | [:controller]
|
14
|
+
# Now it could be defined like this:
|
15
|
+
ext_enum_sets :test_type,
|
16
|
+
raw_level: [:unit_test, :spec],
|
17
|
+
fast: [:raw_level, :controller]
|
18
|
+
```
|
19
|
+
Rem you still need couple `ext_enum_sets` calls if you want to use (`-` / `&` / `^`) array operators except for (`+` / `|`)
|
20
|
+
|
21
|
+
* Definitions now stored as IndifferentHash just as enum originally does
|
22
|
+
and as an Array of strings not a symbols even if defined as ones
|
23
|
+
* Some deprecations warning added
|
24
|
+
|
1
25
|
# 0.4.6
|
2
26
|
* allows enum to enable simple helpers directly at enum definition. Ex:
|
3
27
|
```
|
data/README.md
CHANGED
@@ -22,19 +22,22 @@ Or install it yourself as:
|
|
22
22
|
To use enum extension extend main model class with EnumExt module,
|
23
23
|
and customize your enums the way you need:
|
24
24
|
|
25
|
-
|
26
|
-
extend EnumExt
|
25
|
+
```ruby
|
27
26
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
27
|
+
class SomeModel
|
28
|
+
extend EnumExt
|
29
|
+
|
30
|
+
enum kinds: {}, ext: [:enum_i, :enum_mass_assign, ]
|
31
|
+
humanize_enum #...
|
32
|
+
translate_enum #...
|
33
|
+
ext_enum_sets #...
|
33
34
|
end
|
35
|
+
```
|
34
36
|
|
35
37
|
Let's assume that we have model Request representing some buying requests with enum **status**, and we have model Order with requests,
|
36
38
|
representing single purchase, like this:
|
37
39
|
|
40
|
+
```ruby
|
38
41
|
class Request
|
39
42
|
extend EnumExt
|
40
43
|
belongs_to :order
|
@@ -44,6 +47,7 @@ Or install it yourself as:
|
|
44
47
|
class Order
|
45
48
|
has_many :requests
|
46
49
|
end
|
50
|
+
```
|
47
51
|
|
48
52
|
Now let's review some examples of possible enum extensions
|
49
53
|
|
@@ -51,19 +55,18 @@ Or install it yourself as:
|
|
51
55
|
|
52
56
|
if app doesn't need internationalization, it may use humanize_enum to make enum user friendly
|
53
57
|
|
54
|
-
|
58
|
+
```ruby
|
55
59
|
humanize_enum :status, {
|
56
60
|
#locale dependent example with pluralization and lambda:
|
57
|
-
in_cart: -> (t_self) { I18n.t("request.status.in_cart", count: t_self.sum ) }
|
61
|
+
in_cart: -> (t_self) { I18n.t("request.status.in_cart", count: t_self.sum ) },
|
58
62
|
|
59
63
|
#locale dependent example with pluralization and proc:
|
60
|
-
paid: Proc.new{ I18n.t("request.status.paid", count: self.sum ) }
|
64
|
+
paid: Proc.new{ I18n.t("request.status.paid", count: self.sum ) },
|
61
65
|
|
62
66
|
#locale independent:
|
63
67
|
ready_for_shipment: "Ready to go!"
|
64
68
|
}
|
65
|
-
|
66
|
-
```
|
69
|
+
```
|
67
70
|
|
68
71
|
This humanize_enum adds to instance:
|
69
72
|
- t_in_cart, t_paid, t_ready_for_shipment
|
@@ -76,28 +79,28 @@ Or install it yourself as:
|
|
76
79
|
|
77
80
|
Example with block:
|
78
81
|
|
79
|
-
```
|
80
|
-
|
81
|
-
|
82
|
-
|
82
|
+
```ruby
|
83
|
+
humanize_enum :status do
|
84
|
+
I18n.t("scope.#{status}")
|
85
|
+
end
|
83
86
|
```
|
84
87
|
|
85
88
|
Example for select:
|
86
89
|
|
87
|
-
```
|
90
|
+
```ruby
|
88
91
|
f.select :status, Request.t_statuses_options
|
89
92
|
```
|
90
93
|
|
91
94
|
in Active Admin filters
|
92
|
-
```
|
95
|
+
```ruby
|
93
96
|
filter :status, as: :select, label: 'Status', collection: Request.t_statuses_options_i
|
94
97
|
```
|
95
98
|
|
96
99
|
|
97
|
-
Rem
|
100
|
+
**Rem:** select options may break when using lambda() or proc with instance method, but will survive with block
|
98
101
|
|
99
102
|
Console:
|
100
|
-
```
|
103
|
+
```ruby
|
101
104
|
request.sum = 3
|
102
105
|
request.paid!
|
103
106
|
request.status # >> paid
|
@@ -110,47 +113,55 @@ Or install it yourself as:
|
|
110
113
|
### Translate (translate_enum)
|
111
114
|
|
112
115
|
Enum is translated using scope 'active_record.attributes.class_name_underscore.enum_plural', or the given one:
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
+
```ruby
|
117
|
+
translate_enum :status, 'active_record.request.enum'
|
118
|
+
```
|
116
119
|
Or it can be done with block either with translate or humanize:
|
117
|
-
|
118
|
-
translate_enum :status do
|
119
|
-
I18n.t( "active_record.request.enum.#{status}" )
|
120
|
-
end
|
121
120
|
|
122
|
-
|
121
|
+
```ruby
|
122
|
+
translate_enum :status do
|
123
|
+
I18n.t( "active_record.request.enum.#{status}" )
|
124
|
+
end
|
125
|
+
```
|
123
126
|
|
124
|
-
|
127
|
+
### Enum to_i shortcut ( enum_i )
|
128
|
+
Defines method enum_name_i shortcut for Model.enum_names[elem.enum_name] or enum_name_before_type_cast
|
125
129
|
|
126
130
|
**Ex**
|
127
|
-
|
128
|
-
|
131
|
+
```ruby
|
132
|
+
enum status: [:in_cart, :waiting_for_payment, :paid, :ready_for_shipment, :on_delivery, :delivered],
|
133
|
+
ext: [:enum_i]
|
134
|
+
# some place else:
|
129
135
|
request.paid_i # 10
|
130
|
-
|
136
|
+
```
|
131
137
|
|
132
138
|
### Enum Sets (ext_enum_sets)
|
133
139
|
|
134
|
-
**Use-case**
|
135
|
-
and have scope PayBill.debit, instance method with question mark as usual enum does pay_bill.debit?.
|
140
|
+
**Use-case** whenever you need superset of enums to behave like a enum.
|
136
141
|
|
137
|
-
You can do this with method **ext_enum_sets** it creates:
|
142
|
+
You can do this with method **ext_enum_sets** it creates:
|
143
|
+
- scopes for subsets,
|
144
|
+
- instance methods with `?`
|
145
|
+
- and some class methods helpers
|
138
146
|
|
139
|
-
For
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
147
|
+
For instance:
|
148
|
+
|
149
|
+
```ruby
|
150
|
+
ext_enum_sets :status, {
|
151
|
+
delivery_set: [:ready_for_shipment, :on_delivery, :delivered], # for shipping department for example
|
152
|
+
in_warehouse: [:ready_for_shipment]
|
153
|
+
}
|
154
|
+
```
|
155
|
+
|
146
156
|
it will generate:
|
157
|
+
|
147
158
|
```
|
148
159
|
instance:
|
149
160
|
- methods: delivery_set?, in_warehouse?
|
150
161
|
|
151
162
|
class:
|
152
163
|
- named scopes: delivery_set, in_warehouse
|
153
|
-
- parametrized scopes: with_statuses, without_statuses
|
164
|
+
- parametrized scopes: with_statuses, without_statuses ( available as a standalone extension now, and will not be included by default in a versionafter 0.5.0)
|
154
165
|
class helpers:
|
155
166
|
- delivery_set_statuses (=[:ready_for_shipment, :on_delivery, :delivered] ), in_warehouse_statuses
|
156
167
|
- delivery_set_statuses_i (= [3,4,5]), in_warehouse_statuses_i (=[3])
|
@@ -160,32 +171,45 @@ class:
|
|
160
171
|
- t_delivery_set_statuses_options_i (= [['translation or humanization', 3] ...]) same as above but with integer as value ( for example to use in Active admin filters )
|
161
172
|
```
|
162
173
|
|
163
|
-
```
|
164
|
-
Console:
|
174
|
+
```ruby
|
165
175
|
request.on_delivery!
|
166
176
|
request.delivery_set? # >> true
|
167
|
-
|
177
|
+
|
168
178
|
Request.delivery_set.exists?(request) # >> true
|
169
179
|
Request.in_warehouse.exists?(request) # >> false
|
170
|
-
|
171
|
-
Request.delivery_set_statuses # >> [:ready_for_shipment, :on_delivery, :delivered]
|
172
|
-
|
173
|
-
Request.with_statuses( :payed, :delivery_set ) # >> :payed and [:ready_for_shipment, :on_delivery, :delivered] requests
|
174
|
-
Request.without_statuses( :payed ) # >> scope for all requests with statuses not eq to :payed
|
175
|
-
Request.without_statuses( :payed, :in_warehouse ) # >> scope all requests with statuses not eq to :payed or :ready_for_shipment
|
176
|
-
```
|
177
|
-
|
178
|
-
Rem:
|
179
|
-
ext_enum_sets can be called twice defining a superposition of already defined sets ( considering previous example ):
|
180
180
|
|
181
|
+
Request.delivery_set_statuses # >> ["ready_for_shipment", "on_delivery", "delivered"]
|
182
|
+
```
|
183
|
+
Rem:
|
184
|
+
ext_enum_sets can be called multiple times defining a superposition of already defined sets ( considering previous example ):
|
185
|
+
|
186
|
+
```ruby
|
187
|
+
ext_enum_sets :status, {
|
188
|
+
outside_wharehouse: ( delivery_set_statuses - in_warehouse_statuses )#... any other array operations like &, + and so can be used
|
189
|
+
}
|
181
190
|
```
|
191
|
+
|
192
|
+
Rem: you can refer previously defined set as usual kind in the same method call:
|
193
|
+
|
194
|
+
```ruby
|
182
195
|
ext_enum_sets :status, {
|
183
|
-
|
184
|
-
|
196
|
+
delivery_set: [:ready_for_shipment, :on_delivery, :delivered],
|
197
|
+
not_in_cart: [:paid, :delivery_set] #
|
198
|
+
}
|
185
199
|
```
|
186
200
|
|
187
|
-
|
188
|
-
|
201
|
+
### Multi enum scopes
|
202
|
+
|
203
|
+
```ruby
|
204
|
+
enum status: [:in_cart, :waiting_for_payment, :paid, :ready_for_shipment, :on_delivery, :delivered],
|
205
|
+
ext: [:multi_enum_scopes]
|
206
|
+
|
207
|
+
# some place else:
|
208
|
+
Request.with_statuses( :payed, :delivery_set ) # >> status IN (:payed, :ready_for_shipment, :on_delivery, :delivered)
|
209
|
+
Request.without_statuses( :payed, :in_warehouse ) # >> status NOT IN (:payed, :ready_for_shipment)
|
210
|
+
```
|
211
|
+
|
212
|
+
### Mass-assign ( enum_mass_assign )
|
189
213
|
|
190
214
|
Syntax sugar for mass-assigning enum values.
|
191
215
|
|
@@ -194,23 +218,25 @@ class:
|
|
194
218
|
some_scope.update_all(status: Request.statuses[:new_status], update_at: Time.now)
|
195
219
|
```
|
196
220
|
If you need callbacks you can do like this: some_scope.each(&:new_stat!) but if you don't need callbacks and you
|
197
|
-
have hundreds and thousands of records to change at once you
|
221
|
+
have hundreds and thousands of records to change at once you better call update_all
|
198
222
|
|
199
|
-
```
|
200
|
-
|
223
|
+
```ruby
|
224
|
+
enum status: [:in_cart, :waiting_for_payment, :paid, :ready_for_shipment, :on_delivery, :delivered],
|
225
|
+
ext: [:mass_assign_enum]
|
201
226
|
```
|
202
227
|
|
203
228
|
Console:
|
204
229
|
|
205
|
-
```
|
230
|
+
```ruby
|
206
231
|
request1.in_cart!
|
207
232
|
request2.waiting_for_payment!
|
208
|
-
Request.
|
209
|
-
|
210
|
-
|
233
|
+
Request.not_paid.paid!
|
234
|
+
|
235
|
+
request1.reload.paid? # >> true
|
236
|
+
request2.paid? # >> true
|
211
237
|
request1.updated_at # >> ~ Time.now
|
212
238
|
|
213
|
-
order.requests.already_paid.count
|
239
|
+
order.requests.already_paid.count # >> N
|
214
240
|
order.requests.delivered.count # >> M
|
215
241
|
order.requests.already_paid.delivered!
|
216
242
|
order.requests.already_paid.count # >> 0
|
data/lib/enum_ext/version.rb
CHANGED
data/lib/enum_ext.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
require
|
1
|
+
require "enum_ext/version"
|
2
|
+
require "enum_ext/humanize"
|
2
3
|
|
3
4
|
# Let's assume we have model Request with enum status, and we have model Order with requests like this:
|
4
5
|
# class Request
|
@@ -10,22 +11,78 @@ require 'enum_ext/version'
|
|
10
11
|
# class Order
|
11
12
|
# has_many :requests
|
12
13
|
# end
|
13
|
-
|
14
|
+
|
15
|
+
puts <<~DEPRECATION
|
16
|
+
---------------------DEPRECATION WARNING---------------------------
|
17
|
+
There are TWO MAJOR breaking changes coming into the next version :
|
18
|
+
First deprecation: all major DSL moving major class methods to
|
19
|
+
enum, just for the sake of clarity:
|
20
|
+
|
21
|
+
Ex for enum named kinds it could look like this:
|
22
|
+
|
23
|
+
Class.ext_sets_to_kinds --> Class.kinds.set_to_basic
|
24
|
+
Class.ext_kinds --> Class.kinds.sets
|
25
|
+
Class.all_kinds_defs --> Class.kinds.all
|
26
|
+
Class.t_kinds_options --> Class.kinds.t_options
|
27
|
+
Class.t_named_set_kinds_options --> Class.kinds.t_named_set_options
|
28
|
+
|
29
|
+
Enum extensions preferable way will be using param to original enum call:
|
30
|
+
Ex:
|
31
|
+
#Instead of three method calls:
|
32
|
+
enum kind: {}
|
33
|
+
enum_i :kind
|
34
|
+
enum_mass_assign :kind
|
35
|
+
|
36
|
+
#You should go with ext option instead:
|
37
|
+
enum kinds: {}, ext: [:enum_i, :enum_mass_assign]
|
38
|
+
DEPRECATION
|
39
|
+
|
14
40
|
module EnumExt
|
15
41
|
|
42
|
+
class << self
|
43
|
+
def define_set_to_enum_method( extended_class, enum_plural)
|
44
|
+
# ext_sets_to_kinds( :ready_for_shipment, :delivery_set ) --> [:ready_for_shipment, :on_delivery, :delivered]
|
45
|
+
extended_class.define_singleton_method("ext_sets_to_#{enum_plural}") do |*enum_or_sets|
|
46
|
+
return [] if enum_or_sets.blank?
|
47
|
+
enum_or_sets_strs = enum_or_sets.map(&:to_s)
|
48
|
+
|
49
|
+
next_level_deeper = try("ext_#{enum_plural}").slice( *enum_or_sets_strs ).values.flatten
|
50
|
+
(enum_or_sets_strs & send(enum_plural).keys | send("ext_sets_to_#{enum_plural}", *next_level_deeper)).uniq
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def define_summary_methods(extended_class, enum_plural)
|
55
|
+
extended_class.define_singleton_method("ext_#{enum_plural}") do
|
56
|
+
@enum_ext_summary ||= ActiveSupport::HashWithIndifferentAccess.new
|
57
|
+
end unless respond_to?("ext_#{enum_plural}")
|
58
|
+
|
59
|
+
extended_class.define_singleton_method("all_#{enum_plural}") do
|
60
|
+
{
|
61
|
+
**send(enum_plural),
|
62
|
+
"ext_#{enum_plural}": {
|
63
|
+
**send("ext_#{enum_plural}")
|
64
|
+
}
|
65
|
+
} unless respond_to?("all_#{enum_plural}")
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
16
70
|
# extending enum with inplace settings
|
17
|
-
# enum status: {}, ext: [:enum_i, :mass_assign_enum]
|
71
|
+
# enum status: {}, ext: [:enum_i, :mass_assign_enum, :enum_multi_scopes]
|
18
72
|
# enum_i and mass_assign_enum ara
|
19
73
|
def enum(definitions)
|
20
74
|
extensions = definitions.delete(:ext)
|
21
|
-
|
22
|
-
definitions.
|
23
|
-
|
75
|
+
|
76
|
+
super(definitions).tap do
|
77
|
+
definitions.each do |name,|
|
78
|
+
[*extensions].each{|ext_method| send(ext_method, name) }
|
79
|
+
end
|
24
80
|
end
|
25
81
|
end
|
26
82
|
|
27
|
-
#
|
83
|
+
# Defines instance method a shortcut for getting integer value of an enum.
|
28
84
|
# for enum named 'status' will generate:
|
85
|
+
#
|
29
86
|
# instance.status_i
|
30
87
|
def enum_i( enum_name )
|
31
88
|
define_method "#{enum_name}_i" do
|
@@ -33,9 +90,35 @@ module EnumExt
|
|
33
90
|
end
|
34
91
|
end
|
35
92
|
|
93
|
+
# Defines two scopes for one for an inclusion: `WHERE enum IN( enum1, enum2 )`,
|
94
|
+
# and the second for an exclusion: `WHERE enum NOT IN( enum1, enum2 )`
|
95
|
+
#
|
96
|
+
# Ex:
|
97
|
+
# Request.with_statuses( :payed, :delivery_set ) # >> :payed and [:ready_for_shipment, :on_delivery, :delivered] requests
|
98
|
+
# Request.without_statuses( :payed ) # >> scope for all requests with statuses not eq to :payed
|
99
|
+
# Request.without_statuses( :payed, :in_warehouse ) # >> scope all requests with statuses not eq to :payed or :ready_for_shipment
|
100
|
+
def multi_enum_scopes(enum_name)
|
101
|
+
enum_plural = enum_name.to_s.pluralize
|
102
|
+
|
103
|
+
self.instance_eval do
|
104
|
+
# with_enums scope
|
105
|
+
scope "with_#{enum_plural}", -> (*enum_list) {
|
106
|
+
where( enum_name => send("ext_sets_to_#{enum_plural}", enum_list) )
|
107
|
+
} if !respond_to?("with_#{enum_plural}") && respond_to?(:scope)
|
108
|
+
|
109
|
+
# without_enums scope
|
110
|
+
scope "without_#{enum_plural}", -> (*enum_list) {
|
111
|
+
where.not( enum_name => send("ext_sets_to_#{enum_plural}", enum_list) )
|
112
|
+
} if !respond_to?("without_#{enum_plural}") && respond_to?(:scope)
|
113
|
+
|
114
|
+
EnumExt.define_set_to_enum_method(self, enum_plural)
|
115
|
+
EnumExt.define_summary_methods(self, enum_plural)
|
116
|
+
end
|
117
|
+
end
|
36
118
|
|
37
119
|
# ext_enum_sets
|
38
120
|
# This method intend for creating and using some sets of enum values
|
121
|
+
#
|
39
122
|
# it creates: scopes for subsets,
|
40
123
|
# instance method with ?,
|
41
124
|
# and some class methods helpers
|
@@ -69,53 +152,44 @@ module EnumExt
|
|
69
152
|
# Request.in_warehouse.exists?(request) # >> false
|
70
153
|
#
|
71
154
|
# Request.delivery_set_statuses # >> [:ready_for_shipment, :on_delivery, :delivered]
|
72
|
-
#
|
73
|
-
# Request.with_statuses( :payed, :delivery_set ) # >> :payed and [:ready_for_shipment, :on_delivery, :delivered] requests
|
74
|
-
# Request.without_statuses( :payed ) # >> scope for all requests with statuses not eq to :payed
|
75
|
-
# Request.without_statuses( :payed, :in_warehouse ) # >> scope all requests with statuses not eq to :payed or :ready_for_shipment
|
76
|
-
#
|
77
155
|
|
78
156
|
#Rem:
|
79
157
|
# ext_enum_sets can be called twice defining a superposition of already defined sets ( considering previous example ):
|
80
158
|
# ext_enum_sets :status, {
|
81
|
-
#
|
159
|
+
# outside_warehouse: ( delivery_set_statuses - in_warehouse_statuses )... any other array operations like &, + and so can be used
|
82
160
|
# }
|
83
161
|
def ext_enum_sets( enum_name, options = {} )
|
84
162
|
enum_plural = enum_name.to_s.pluralize
|
85
163
|
|
86
164
|
self.instance_eval do
|
87
|
-
|
88
|
-
|
89
|
-
end unless respond_to?("ext_#{enum_plural}")
|
90
|
-
|
91
|
-
send("ext_#{enum_plural}").merge!( options )
|
165
|
+
EnumExt.define_set_to_enum_method(self, enum_plural)
|
166
|
+
EnumExt.define_summary_methods(self, enum_plural)
|
92
167
|
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
168
|
+
puts(<<~DEPRECATION) unless respond_to?("with_#{enum_plural}")
|
169
|
+
----------------DEPRECATION WARNING----------------
|
170
|
+
- with/without_#{enum_plural} are served now via multi_enum_scopes method,
|
171
|
+
and will be removed from the ext_enum_sets in the next version!
|
172
|
+
DEPRECATION
|
173
|
+
multi_enum_scopes(enum_name)
|
98
174
|
|
99
|
-
#
|
100
|
-
scope "without_#{enum_plural}", -> (sets_arr) {
|
101
|
-
where.not( id: self.send("with_#{enum_plural}", sets_arr) )
|
102
|
-
} if !respond_to?("without_#{enum_plural}") && respond_to?(:scope)
|
175
|
+
send("ext_#{enum_plural}").merge!( options.transform_values{ _1.map(&:to_s) } )
|
103
176
|
|
104
177
|
options.each do |set_name, enum_vals|
|
105
178
|
# set_name scope
|
106
|
-
scope set_name, -> { where( enum_name =>
|
179
|
+
scope set_name, -> { where( enum_name => send("#{set_name}_#{enum_plural}") ) } if respond_to?(:scope)
|
107
180
|
|
108
|
-
|
181
|
+
# class.enum_set_values
|
109
182
|
define_singleton_method( "#{set_name}_#{enum_plural}" ) do
|
110
|
-
enum_vals
|
183
|
+
send("ext_sets_to_#{enum_plural}", *enum_vals)
|
111
184
|
end
|
112
185
|
|
113
|
-
#
|
114
|
-
|
115
|
-
|
186
|
+
# instance.set_name?
|
187
|
+
define_method "#{set_name}?" do
|
188
|
+
send(enum_name) && self.class.send( "#{set_name}_#{enum_plural}" ).include?( send(enum_name) )
|
116
189
|
end
|
117
190
|
|
118
191
|
# t_... - are translation dependent methods
|
192
|
+
# This one is a narrow case helpers just a quick subset of t_ enums options for a set
|
119
193
|
# class.t_enums_options
|
120
194
|
define_singleton_method( "t_#{set_name}_#{enum_plural}_options" ) do
|
121
195
|
return [["Enum translations call missed. Did you forget to call translate #{enum_name}"]*2] unless respond_to?( "t_#{enum_plural}_options_raw" )
|
@@ -130,28 +204,25 @@ module EnumExt
|
|
130
204
|
send("t_#{enum_plural}_options_raw_i", send("t_#{set_name}_#{enum_plural}") )
|
131
205
|
end
|
132
206
|
|
133
|
-
# instance.set_name?
|
134
|
-
define_method "#{set_name}?" do
|
135
|
-
self.send(enum_name) && ( enum_vals.include?( self.send(enum_name) ) || enum_vals.include?( self.send(enum_name).to_sym ))
|
136
|
-
end
|
137
|
-
|
138
207
|
# protected?
|
139
|
-
# class.
|
208
|
+
# class.t_set_name_enums ( translations or humanizations subset for a given set )
|
140
209
|
define_singleton_method( "t_#{set_name}_#{enum_plural}" ) do
|
141
210
|
return [(["Enum translations call missed. Did you forget to call translate #{enum_name}"]*2)].to_h unless respond_to?( "t_#{enum_plural}" )
|
142
211
|
|
143
|
-
send( "t_#{enum_plural}" ).slice( *
|
212
|
+
send( "t_#{enum_plural}" ).slice( *send("#{set_name}_#{enum_plural}") )
|
144
213
|
end
|
145
214
|
end
|
146
215
|
end
|
147
216
|
end
|
148
217
|
|
149
218
|
# Ex mass_assign_enum
|
219
|
+
#
|
150
220
|
# Used for mass assigning for collection without callbacks it creates bang methods for collections using update_all.
|
151
221
|
# it's often case when you need bulk update without callbacks, so it's gets frustrating to repeat:
|
152
222
|
# some_scope.update_all(status: Request.statuses[:new_status], update_at: Time.now)
|
153
|
-
#
|
154
|
-
#
|
223
|
+
#
|
224
|
+
# If you need callbacks you can do like this: some_scope.each(&:new_stat!) but if you don't need callbacks
|
225
|
+
# and you have lots of records to change at once you need update_all
|
155
226
|
#
|
156
227
|
# mass_assign_enum( :status )
|
157
228
|
#
|
@@ -162,14 +233,13 @@ module EnumExt
|
|
162
233
|
# request1.in_cart!
|
163
234
|
# request2.waiting_for_payment!
|
164
235
|
# Request.with_statuses( :in_cart, :waiting_for_payment ).payed!
|
165
|
-
# request1.paid?
|
166
|
-
# request2.paid?
|
236
|
+
# request1.paid? # >> true
|
237
|
+
# request2.paid? # >> true
|
167
238
|
# request1.updated_at # >> Time.now
|
168
|
-
# defined?(Request::MassAssignEnum) # >> true
|
169
239
|
#
|
170
|
-
# order.requests.paid.all?(&:paid?)
|
240
|
+
# order.requests.paid.all?(&:paid?) # >> true
|
171
241
|
# order.requests.paid.delivered!
|
172
|
-
# order.requests.map(&:status).uniq
|
242
|
+
# order.requests.map(&:status).uniq #>> [:delivered]
|
173
243
|
|
174
244
|
def mass_assign_enum( *enums_names )
|
175
245
|
enums_names.each do |enum_name|
|
@@ -182,10 +252,12 @@ module EnumExt
|
|
182
252
|
end
|
183
253
|
end
|
184
254
|
end
|
255
|
+
alias_method :enum_mass_assign, :mass_assign_enum
|
185
256
|
|
186
257
|
# if app doesn't need internationalization, it may use humanize_enum to make enum user friendly
|
258
|
+
#
|
187
259
|
# class Request
|
188
|
-
#
|
260
|
+
# humanize_enum :status, {
|
189
261
|
# #locale dependent example with pluralization and lambda:
|
190
262
|
# payed: -> (t_self) { I18n.t("request.status.payed", count: t_self.sum ) }
|
191
263
|
#
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: enum_ext
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- alekseyl
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-
|
11
|
+
date: 2023-02-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|