enum_ext 0.4.6 → 0.5.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/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
|