enum_ext 0.2.1 → 0.3.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/Gemfile.lock +57 -17
- data/README.md +138 -143
- data/Rakefile +8 -1
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/enum_ext.gemspec +8 -5
- data/lib/enum_ext/version.rb +1 -1
- data/lib/enum_ext.rb +145 -160
- metadata +51 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8d87b2abcd1fc85e6b40920b0623a190a8b6ae8e
|
4
|
+
data.tar.gz: cfdcb6362c984922ef6047a4ec719363312d8b26
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e921603dd1328763efef7dbd5ac36e335037d4d381e4361c3c5dcf2453503e326876a42935ad679e257e6109e6d74b5aee49782047835eb70f3880c34ef76ff2
|
7
|
+
data.tar.gz: f6ecf63202ba792af34678ecae8f3bc73ca051894e931aebe21b2eb1de4887577f4728e06727a6e814c318a761b2b52bfdb41c8b47226abce5682db4d1676c6f
|
data/Gemfile.lock
CHANGED
@@ -1,33 +1,70 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
enum_ext (0.
|
4
|
+
enum_ext (0.3.0)
|
5
5
|
activerecord (>= 4.1)
|
6
6
|
|
7
7
|
GEM
|
8
8
|
remote: https://rubygems.org/
|
9
9
|
specs:
|
10
|
-
|
11
|
-
|
10
|
+
actionpack (5.0.2)
|
11
|
+
actionview (= 5.0.2)
|
12
|
+
activesupport (= 5.0.2)
|
13
|
+
rack (~> 2.0)
|
14
|
+
rack-test (~> 0.6.3)
|
15
|
+
rails-dom-testing (~> 2.0)
|
16
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
17
|
+
actionview (5.0.2)
|
18
|
+
activesupport (= 5.0.2)
|
12
19
|
builder (~> 3.1)
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
20
|
+
erubis (~> 2.7.0)
|
21
|
+
rails-dom-testing (~> 2.0)
|
22
|
+
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
23
|
+
activemodel (5.0.2)
|
24
|
+
activesupport (= 5.0.2)
|
25
|
+
activerecord (5.0.2)
|
26
|
+
activemodel (= 5.0.2)
|
27
|
+
activesupport (= 5.0.2)
|
28
|
+
arel (~> 7.0)
|
29
|
+
activesupport (5.0.2)
|
30
|
+
concurrent-ruby (~> 1.0, >= 1.0.2)
|
18
31
|
i18n (~> 0.7)
|
19
|
-
json (~> 1.7, >= 1.7.7)
|
20
32
|
minitest (~> 5.1)
|
21
|
-
thread_safe (~> 0.3, >= 0.3.4)
|
22
33
|
tzinfo (~> 1.1)
|
23
|
-
arel (
|
24
|
-
builder (3.2.
|
25
|
-
|
26
|
-
|
34
|
+
arel (7.1.4)
|
35
|
+
builder (3.2.3)
|
36
|
+
concurrent-ruby (1.0.5)
|
37
|
+
erubis (2.7.0)
|
38
|
+
i18n (0.8.1)
|
39
|
+
loofah (2.0.3)
|
40
|
+
nokogiri (>= 1.5.9)
|
41
|
+
method_source (0.8.2)
|
42
|
+
mini_portile2 (2.1.0)
|
27
43
|
minitest (5.8.3)
|
44
|
+
nokogiri (1.7.1)
|
45
|
+
mini_portile2 (~> 2.1.0)
|
46
|
+
rack (2.0.1)
|
47
|
+
rack-test (0.6.3)
|
48
|
+
rack (>= 1.0)
|
49
|
+
rails-dom-testing (2.0.2)
|
50
|
+
activesupport (>= 4.2.0, < 6.0)
|
51
|
+
nokogiri (~> 1.6)
|
52
|
+
rails-html-sanitizer (1.0.3)
|
53
|
+
loofah (~> 2.0)
|
54
|
+
rails-i18n (5.0.3)
|
55
|
+
i18n (~> 0.7)
|
56
|
+
railties (~> 5.0)
|
57
|
+
railties (5.0.2)
|
58
|
+
actionpack (= 5.0.2)
|
59
|
+
activesupport (= 5.0.2)
|
60
|
+
method_source
|
61
|
+
rake (>= 0.8.7)
|
62
|
+
thor (>= 0.18.1, < 2.0)
|
28
63
|
rake (10.4.2)
|
29
|
-
|
30
|
-
|
64
|
+
sqlite3 (1.3.13)
|
65
|
+
thor (0.19.4)
|
66
|
+
thread_safe (0.3.6)
|
67
|
+
tzinfo (1.2.3)
|
31
68
|
thread_safe (~> 0.1)
|
32
69
|
|
33
70
|
PLATFORMS
|
@@ -36,7 +73,10 @@ PLATFORMS
|
|
36
73
|
DEPENDENCIES
|
37
74
|
bundler (~> 1.11)
|
38
75
|
enum_ext!
|
76
|
+
minitest
|
77
|
+
rails-i18n (>= 4)
|
39
78
|
rake (~> 10.0)
|
79
|
+
sqlite3
|
40
80
|
|
41
81
|
BUNDLED WITH
|
42
|
-
1.
|
82
|
+
1.14.6
|
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# EnumExt
|
2
2
|
|
3
|
-
EnumExt extends rails enum adding localization
|
3
|
+
EnumExt extends rails enum adding localization/translation and it's helpers, mass-assign on scopes with bang, advanced sets logic over existing.
|
4
4
|
|
5
5
|
## Installation
|
6
6
|
|
@@ -24,18 +24,20 @@ Or install it yourself as:
|
|
24
24
|
class SomeModel
|
25
25
|
extend EnumExt
|
26
26
|
|
27
|
+
enum_i ...
|
27
28
|
humanize_enum ...
|
28
29
|
translate_enum ...
|
29
30
|
ext_enum_sets ...
|
30
31
|
mass_assign_enum ...
|
31
32
|
end
|
32
33
|
|
33
|
-
Let's assume that we have model Request representing some buying requests with enum **status**, and we have model Order with requests,
|
34
|
+
Let's assume that we have model Request representing some buying requests with enum **status**, and we have model Order with requests,
|
35
|
+
representing single purchase, like this:
|
34
36
|
|
35
37
|
class Request
|
36
38
|
extend EnumExt
|
37
39
|
belongs_to :order
|
38
|
-
enum status: [ :in_cart, :waiting_for_payment, :
|
40
|
+
enum status: [ :in_cart, :waiting_for_payment, :paid, :ready_for_shipment, :on_delivery, :delivered ]
|
39
41
|
end
|
40
42
|
|
41
43
|
class Order
|
@@ -46,48 +48,65 @@ Or install it yourself as:
|
|
46
48
|
|
47
49
|
### Humanization (humanize_enum)
|
48
50
|
|
49
|
-
|
50
|
-
...
|
51
|
-
localize_enum :status, {
|
52
|
-
|
53
|
-
#locale dependent example with internal pluralization and lambda:
|
54
|
-
payed: -> (t_self) { I18n.t("request.status.payed", count: t_self.sum ) }
|
55
|
-
|
56
|
-
#locale dependent example with internal pluralization and proc:
|
57
|
-
payed: proc { I18n.t("request.status.payed", count: sum ) }
|
58
|
-
|
59
|
-
#locale independent:
|
60
|
-
ready_for_shipment: "Ready to go!"
|
61
|
-
}
|
62
|
-
end
|
63
|
-
|
64
|
-
Console:
|
65
|
-
|
66
|
-
request.sum = 3
|
67
|
-
request.payed!
|
68
|
-
request.status # >> payed
|
69
|
-
request.t_status # >> "Payed 3 dollars"
|
70
|
-
Request.t_statuses # >> { in_cart: -> { I18n.t("request.status.in_cart") }, .... }
|
71
|
-
|
72
|
-
If you need some substitution you can go like this:
|
51
|
+
if app doesn't need internationalization, it may use humanize_enum to make enum user friendly
|
73
52
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
53
|
+
```
|
54
|
+
humanize_enum :status, {
|
55
|
+
#locale dependent example with pluralization and lambda:
|
56
|
+
in_cart: -> (t_self) { I18n.t("request.status.in_cart", count: t_self.sum ) }
|
57
|
+
|
58
|
+
#locale dependent example with pluralization and proc:
|
59
|
+
paid: Proc.new{ I18n.t("request.status.paid", count: self.sum ) }
|
60
|
+
|
61
|
+
#locale independent:
|
62
|
+
ready_for_shipment: "Ready to go!"
|
63
|
+
}
|
64
|
+
end
|
65
|
+
```
|
66
|
+
|
67
|
+
This call adds to instance:
|
68
|
+
- t_in_cart, t_paid, t_ready_for_shipment
|
69
|
+
|
70
|
+
adds to class:
|
71
|
+
- t_statuses - as given or generated values
|
72
|
+
- t_statuses_options - translated enum values options for select input
|
73
|
+
- t_statuses_options_i - same as above but use int values with translations works for ActiveAdmin filters for instance
|
83
74
|
|
84
|
-
|
85
|
-
|
86
|
-
f.select :status, Request.t_delivery_set_statuses_options
|
75
|
+
|
76
|
+
Example with block:
|
87
77
|
|
78
|
+
```
|
79
|
+
humanize_enum :status do
|
80
|
+
I18n.t("scope.#{status}")
|
81
|
+
end
|
82
|
+
```
|
83
|
+
|
84
|
+
Example for select:
|
85
|
+
|
86
|
+
```
|
87
|
+
f.select :status, Request.t_statuses_options
|
88
|
+
```
|
89
|
+
|
90
|
+
in Active Admin filters
|
91
|
+
```
|
92
|
+
filter :status, as: :select, label: 'Status', collection: Request.t_statuses_options_i
|
93
|
+
```
|
94
|
+
|
95
|
+
|
96
|
+
Rem: select options may break when using lambda() or proc with instance method, but will survive with block
|
97
|
+
|
98
|
+
Console:
|
99
|
+
```
|
100
|
+
request.sum = 3
|
101
|
+
request.paid!
|
102
|
+
request.status # >> paid
|
103
|
+
request.t_status # >> "paid 3 dollars"
|
104
|
+
Request.t_statuses # >> { in_cart: -> { I18n.t("request.status.in_cart") }, .... }
|
105
|
+
```
|
106
|
+
|
88
107
|
### Translate (translate_enum)
|
89
108
|
|
90
|
-
Enum is translated using scope 'active_record.attributes.class_name_underscore.
|
109
|
+
Enum is translated using scope 'active_record.attributes.class_name_underscore.enum_plural', or the given one:
|
91
110
|
|
92
111
|
translate_enum :status, 'active_record.request.enum'
|
93
112
|
|
@@ -97,9 +116,6 @@ Or it can be done with block either with translate or humanize:
|
|
97
116
|
I18n.t( "active_record.request.enum.#{status}" )
|
98
117
|
end
|
99
118
|
|
100
|
-
Also since we place by default enum translation in same place as enum name translation
|
101
|
-
human_attribute_name is redefined so it will work fine in ActiveAdmin, but you need to add translation to locale.
|
102
|
-
|
103
119
|
### Enum to_i shortcut ( enum_i )
|
104
120
|
|
105
121
|
Defines method enum_name_i shortcut for Model.enum_names[elem.enum_name]
|
@@ -107,125 +123,101 @@ Defines method enum_name_i shortcut for Model.enum_names[elem.enum_name]
|
|
107
123
|
**Ex**
|
108
124
|
enum_i :status
|
109
125
|
...
|
110
|
-
request.
|
126
|
+
request.paid_i # 10
|
111
127
|
|
112
128
|
|
113
129
|
### Enum Sets (ext_enum_sets)
|
114
130
|
|
115
|
-
**Use-case** For example you have pay bills of different types, and you want to group some types in debit and credit "super-types",
|
131
|
+
**Use-case** For example you have pay bills of different types, and you want to group some types in debit and credit "super-types",
|
132
|
+
and have scope PayBill.debit, instance method with question mark as usual enum does pay_bill.debit?.
|
116
133
|
|
117
|
-
You can do this with method **ext_enum_sets
|
134
|
+
You can do this with method **ext_enum_sets** it creates: scopes for subsets, instance method with ? and some class methods helpers
|
135
|
+
|
136
|
+
For this call:
|
137
|
+
```
|
138
|
+
ext_enum_sets :status, {
|
139
|
+
delivery_set: [:ready_for_shipment, :on_delivery, :delivered] # for shipping department for example
|
140
|
+
in_warehouse: [:ready_for_shipment] # this just for superposition example below
|
141
|
+
}
|
142
|
+
```
|
143
|
+
|
144
|
+
it will generate:
|
145
|
+
instance:
|
146
|
+
methods: delivery_set?, in_warehouse?
|
147
|
+
class:
|
148
|
+
named scopes: delivery_set, in_warehouse
|
149
|
+
parametrized scopes: with_statuses, without_statuses
|
150
|
+
class helpers:
|
151
|
+
- delivery_set_statuses (=[:ready_for_shipment, :on_delivery, :delivered] ), in_warehouse_statuses
|
152
|
+
- delivery_set_statuses_i (= [3,4,5]), in_warehouse_statuses_i (=[3])
|
153
|
+
class translation helpers ( started with t_... )
|
154
|
+
for select inputs purposes:
|
155
|
+
- t_delivery_set_statuses_options (= [['translation or humanization', :ready_for_shipment] ...])
|
156
|
+
same as above but with integer as value ( for example to use in Active admin filters )
|
157
|
+
- t_delivery_set_statuses_options_i (= [['translation or humanization', 3] ...])
|
158
|
+
```
|
159
|
+
Console:
|
160
|
+
request.on_delivery!
|
161
|
+
request.delivery_set? # >> true
|
118
162
|
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
request.waiting_for_payment!
|
139
|
-
request.non_payed? # >> true
|
140
|
-
|
141
|
-
Request.non_payed.exists?(request) # >> true
|
142
|
-
Request.delivery_set.exists?(request) # >> false
|
143
|
-
|
144
|
-
Request.non_payed_statuses # >> [:in_cart, :waiting_for_payment]
|
145
|
-
|
146
|
-
Request.with_statuses( :payed, :in_cart ) # >> scope for all in_cart and payed requests
|
147
|
-
Request.without_statuses( :payed ) # >> scope for all requests with statuses not eq to payed
|
148
|
-
Request.without_statuses( :payed, :non_payed ) # >> scope all requests with statuses not eq to payed and in_cart + waiting_for_payment
|
149
|
-
|
150
|
-
|
151
|
-
#### Rem:
|
152
|
-
|
153
|
-
You can call ext_enum_sets more than one time defining a superposition of already defined sets:
|
154
|
-
|
155
|
-
class Request
|
156
|
-
...
|
157
|
-
ext_enum_sets (... first time you call ext_enum_sets )
|
158
|
-
ext_enum_sets :status, {
|
159
|
-
already_payed: ( [:payed] | delivery_set_statuses ),
|
160
|
-
outside_wharehouse: ( delivery_set_statuses - in_warehouse_statuses )... # any other array operations like &, + and so can be used
|
161
|
-
}
|
162
|
-
|
163
|
+
Request.delivery_set.exists?(request) # >> true
|
164
|
+
Request.in_warehouse.exists?(request) # >> false
|
165
|
+
|
166
|
+
Request.delivery_set_statuses # >> [:ready_for_shipment, :on_delivery, :delivered]
|
167
|
+
|
168
|
+
Request.with_statuses( :payed, :delivery_set ) # >> :payed and [:ready_for_shipment, :on_delivery, :delivered] requests
|
169
|
+
Request.without_statuses( :payed ) # >> scope for all requests with statuses not eq to :payed
|
170
|
+
Request.without_statuses( :payed, :in_warehouse ) # >> scope all requests with statuses not eq to :payed or :ready_for_shipment
|
171
|
+
```
|
172
|
+
|
173
|
+
Rem:
|
174
|
+
ext_enum_sets can be called twice defining a superposition of already defined sets ( considering previous example ):
|
175
|
+
|
176
|
+
```
|
177
|
+
ext_enum_sets :status, {
|
178
|
+
outside_wharehouse: ( delivery_set_statuses - in_warehouse_statuses )... any other array operations like &, + and so can be used
|
179
|
+
}
|
180
|
+
```
|
163
181
|
|
182
|
+
|
164
183
|
### Mass-assign ( mass_assign_enum )
|
165
184
|
|
166
185
|
Syntax sugar for mass-assigning enum values.
|
167
186
|
|
168
|
-
**Use-case:** it's often case when I need bulk update without callbacks, so it's gets frustrating to repeat:
|
169
|
-
|
187
|
+
**Use-case:** it's often case when I need bulk update without callbacks, so it's gets frustrating to repeat:
|
188
|
+
```
|
189
|
+
some_scope.update_all(status: Request.statuses[:new_status], update_at: Time.now)
|
190
|
+
```
|
191
|
+
If you need callbacks you can do like this: some_scope.each(&:new_stat!) but if you don't need callbacks and you
|
192
|
+
has hundreds and thousands of records to change at once you need update_all
|
170
193
|
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
end
|
194
|
+
```
|
195
|
+
mass_assign_enum( :status )
|
196
|
+
```
|
175
197
|
|
176
198
|
Console:
|
177
|
-
|
178
|
-
request1.in_cart!
|
179
|
-
request2.waiting_for_payment!
|
180
|
-
Request.non_payed.payed!
|
181
|
-
request1.payed? # >> true
|
182
|
-
request2.payed? # >> true
|
183
|
-
request1.updated_at # >> ~ Time.now
|
184
|
-
defined?(Request::MassAssignEnum) # >> true
|
185
|
-
|
186
|
-
|
187
|
-
order.requests.already_payed.count # >> N
|
188
|
-
order.requests.delivered.count # >> M
|
189
|
-
order.requests.already_payed.delivered!
|
190
|
-
order.requests.already_payed.count # >> 0
|
191
|
-
order.requests.delivered.count # >> N + M
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
####Rem:
|
196
|
-
|
197
|
-
**mass_assign_enum** accepts additional options as last argument. Calling
|
198
|
-
|
199
|
-
mass_assign_enum( :status )
|
200
|
-
|
201
|
-
actually is equal to call:
|
202
|
-
|
203
|
-
mass_assign_enum( :status, { relation: true, association_relation: true } )
|
204
|
-
|
205
|
-
###### Meaning:
|
206
|
-
|
207
|
-
relation: true - Request.some_scope.payed! - works
|
208
|
-
|
209
|
-
association_relation: true - Order.first.requests.scope.new_stat! - works
|
210
|
-
|
211
|
-
**but it wouldn't work without 'scope' part!** If you want to use it without 'scope' you may do it this way:
|
212
|
-
|
213
|
-
class Request
|
214
|
-
...
|
215
|
-
mass_assign_enum( :status, relation: true, association_relation: false )
|
216
|
-
end
|
217
199
|
|
218
|
-
|
219
|
-
|
220
|
-
|
200
|
+
```
|
201
|
+
request1.in_cart!
|
202
|
+
request2.waiting_for_payment!
|
203
|
+
Request.non_paid.paid!
|
204
|
+
request1.paid? # >> true
|
205
|
+
request2.paid? # >> true
|
206
|
+
request1.updated_at # >> ~ Time.now
|
207
|
+
defined?(Request::MassAssignEnum) # >> true
|
208
|
+
|
221
209
|
|
222
|
-
|
210
|
+
order.requests.already_paid.count # >> N
|
211
|
+
order.requests.delivered.count # >> M
|
212
|
+
order.requests.already_paid.delivered!
|
213
|
+
order.requests.already_paid.count # >> 0
|
214
|
+
order.requests.delivered.count # >> N + M
|
215
|
+
```
|
216
|
+
|
223
217
|
|
224
|
-
#### Rem2:
|
225
|
-
You can mass-assign more than one enum ::MassAssignEnum module will contain mass assign for both. It will break nothing since all enum name must be uniq across model
|
226
218
|
|
227
219
|
## Tests
|
228
|
-
|
220
|
+
rake test
|
229
221
|
|
230
222
|
## Development
|
231
223
|
|
@@ -239,3 +231,6 @@ Bug reports and pull requests are welcome on GitHub at https://github.com/alekse
|
|
239
231
|
|
240
232
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
241
233
|
|
234
|
+
### Thanks
|
235
|
+
|
236
|
+
Thanks for the star vzamanillo, it inspires me to do mass refactor and gracefully cover code in this gem by tests.
|
data/Rakefile
CHANGED
data/bin/console
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require "enum_ext"
|
5
|
+
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
8
|
+
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
10
|
+
# require "pry"
|
11
|
+
# Pry.start
|
12
|
+
|
13
|
+
require "irb"
|
14
|
+
IRB.start
|
data/bin/setup
ADDED
data/enum_ext.gemspec
CHANGED
@@ -9,8 +9,8 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["alekseyl"]
|
10
10
|
spec.email = ["leshchuk@gmail.com"]
|
11
11
|
|
12
|
-
spec.summary = %q{Enum extension, ads enum sets, mass-assign
|
13
|
-
spec.description = %q{Enum extension, ads enum sets, mass-assign
|
12
|
+
spec.summary = %q{Enum extension, ads enum sets, mass-assign, localization, and some sugar helpers.}
|
13
|
+
spec.description = %q{Enum extension, ads enum sets, mass-assign, localization, and some sugar helpers.}
|
14
14
|
spec.homepage = "https://github.com/alekseyl/enum_ext"
|
15
15
|
spec.license = "MIT"
|
16
16
|
|
@@ -19,8 +19,11 @@ Gem::Specification.new do |spec|
|
|
19
19
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
20
|
spec.require_paths = ["lib"]
|
21
21
|
|
22
|
-
spec.add_dependency
|
22
|
+
spec.add_dependency 'activerecord', '>=4.1'
|
23
23
|
|
24
|
-
spec.add_development_dependency
|
25
|
-
spec.add_development_dependency
|
24
|
+
spec.add_development_dependency 'minitest'
|
25
|
+
spec.add_development_dependency 'bundler', '~> 1.11'
|
26
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
27
|
+
spec.add_development_dependency 'rails-i18n', '>=4'
|
28
|
+
spec.add_development_dependency 'sqlite3'
|
26
29
|
end
|
data/lib/enum_ext/version.rb
CHANGED
data/lib/enum_ext.rb
CHANGED
@@ -1,10 +1,10 @@
|
|
1
|
-
require
|
1
|
+
require 'enum_ext/version'
|
2
2
|
|
3
3
|
# Let's assume we have model Request with enum status, and we have model Order with requests like this:
|
4
4
|
# class Request
|
5
5
|
# extend EnumExt
|
6
6
|
# belongs_to :order
|
7
|
-
# enum status:
|
7
|
+
# enum status: { in_cart: 0, waiting_for_payment: 1, payed: 2, ready_for_shipment: 3, on_delivery: 4, delivered: 5 }
|
8
8
|
# end
|
9
9
|
#
|
10
10
|
# class Order
|
@@ -13,6 +13,9 @@ require "enum_ext/version"
|
|
13
13
|
#
|
14
14
|
module EnumExt
|
15
15
|
|
16
|
+
# defines shortcut for getting integer value of enum.
|
17
|
+
# for enum named status will generate:
|
18
|
+
# instance.status_i
|
16
19
|
def enum_i( enum_name )
|
17
20
|
define_method "#{enum_name}_i" do
|
18
21
|
self.class.send("#{enum_name.to_s.pluralize}")[send(enum_name)].to_i
|
@@ -20,175 +23,158 @@ module EnumExt
|
|
20
23
|
end
|
21
24
|
|
22
25
|
|
23
|
-
#
|
24
|
-
# This method intend for creating and using some sets of enum values
|
25
|
-
# it creates: scopes for subsets
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
# #class scopes: non_payed, delivery_set, in_warehouse
|
31
|
-
# #class scopes: with_statuses, without_statuses
|
32
|
-
# #class non_payed_statuses, delivery_set_statuses ( = [:in_cart, :waiting_for_payment], [:ready_for_shipment, :on_delivery, :delivered].. )
|
26
|
+
# ext_enum_sets
|
27
|
+
# This method intend for creating and using some sets of enum values
|
28
|
+
# it creates: scopes for subsets,
|
29
|
+
# instance method with ?,
|
30
|
+
# and some class methods helpers
|
31
|
+
#
|
32
|
+
# For this call:
|
33
33
|
# ext_enum_sets :status, {
|
34
|
-
# non_payed: [:in_cart, :waiting_for_payment],
|
35
34
|
# delivery_set: [:ready_for_shipment, :on_delivery, :delivered] # for shipping department for example
|
36
|
-
# in_warehouse: [:ready_for_shipment]
|
35
|
+
# in_warehouse: [:ready_for_shipment] # this just for superposition example below
|
37
36
|
# }
|
38
|
-
#
|
37
|
+
#
|
38
|
+
# it will generate:
|
39
|
+
# instance:
|
40
|
+
# methods: delivery_set?, in_warehouse?
|
41
|
+
# class:
|
42
|
+
# named scopes: delivery_set, in_warehouse
|
43
|
+
# parametrized scopes: with_statuses, without_statuses
|
44
|
+
# class helpers:
|
45
|
+
# - delivery_set_statuses (=[:ready_for_shipment, :on_delivery, :delivered] ), in_warehouse_statuses
|
46
|
+
# - delivery_set_statuses_i (= [3,4,5]), in_warehouse_statuses_i (=[3])
|
47
|
+
# class translation helpers ( started with t_... )
|
48
|
+
# for select inputs purposes:
|
49
|
+
# - t_delivery_set_statuses_options (= [['translation or humanization', :ready_for_shipment] ...])
|
50
|
+
# same as above but with integer as value ( for example to use in Active admin filters )
|
51
|
+
# - t_delivery_set_statuses_options_i (= [['translation or humanization', 3] ...])
|
39
52
|
|
40
53
|
# Console:
|
41
|
-
# request.
|
42
|
-
# request.
|
43
|
-
|
44
|
-
# Request.non_payed.exists?(request) # >> true
|
45
|
-
# Request.delivery_set.exists?(request) # >> false
|
54
|
+
# request.on_delivery!
|
55
|
+
# request.delivery_set? # >> true
|
46
56
|
|
47
|
-
# Request.
|
57
|
+
# Request.delivery_set.exists?(request) # >> true
|
58
|
+
# Request.in_warehouse.exists?(request) # >> false
|
48
59
|
#
|
49
|
-
# Request.
|
50
|
-
#
|
51
|
-
# Request.
|
60
|
+
# Request.delivery_set_statuses # >> [:ready_for_shipment, :on_delivery, :delivered]
|
61
|
+
#
|
62
|
+
# Request.with_statuses( :payed, :delivery_set ) # >> :payed and [:ready_for_shipment, :on_delivery, :delivered] requests
|
63
|
+
# Request.without_statuses( :payed ) # >> scope for all requests with statuses not eq to :payed
|
64
|
+
# Request.without_statuses( :payed, :in_warehouse ) # >> scope all requests with statuses not eq to :payed or :ready_for_shipment
|
52
65
|
#
|
53
66
|
|
54
67
|
#Rem:
|
55
|
-
# ext_enum_sets can be called twice defining a
|
56
|
-
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
# ext_enum_sets :status, {
|
60
|
-
# already_payed: ( [:payed] | delivery_set_statuses ),
|
61
|
-
# outside_wharehouse: ( delivery_set_statuses - in_warehouse_statuses )... any other array operations like &, + and so can be used
|
62
|
-
# }
|
68
|
+
# ext_enum_sets can be called twice defining a superposition of already defined sets ( considering previous example ):
|
69
|
+
# ext_enum_sets :status, {
|
70
|
+
# outside_wharehouse: ( delivery_set_statuses - in_warehouse_statuses )... any other array operations like &, + and so can be used
|
71
|
+
# }
|
63
72
|
def ext_enum_sets( enum_name, options )
|
64
73
|
enum_plural = enum_name.to_s.pluralize
|
65
74
|
|
66
75
|
self.instance_eval do
|
67
76
|
options.each do |set_name, enum_vals|
|
77
|
+
# set_name scope
|
68
78
|
scope set_name, -> { where( enum_name => self.send( enum_plural ).slice( *enum_vals.map(&:to_s) ).values ) }
|
69
79
|
|
80
|
+
# with_enums scope
|
81
|
+
scope "with_#{enum_plural}", -> (sets_arr) {
|
82
|
+
where( enum_name => self.send( enum_plural ).slice(
|
83
|
+
*sets_arr.map{|set_name| self.try( "#{set_name}_#{enum_plural}" ) || set_name }.flatten.uniq.map(&:to_s) ).values )
|
84
|
+
} unless respond_to?("with_#{enum_plural}")
|
85
|
+
|
86
|
+
# without_enums scope
|
87
|
+
scope "without_#{enum_plural}", -> (sets_arr) {
|
88
|
+
where.not( id: self.send("with_#{enum_plural}", sets_arr) )
|
89
|
+
} unless respond_to?("without_#{enum_plural}")
|
90
|
+
|
70
91
|
|
92
|
+
# class.enum_set_values
|
71
93
|
define_singleton_method( "#{set_name}_#{enum_plural}" ) do
|
72
94
|
enum_vals
|
73
95
|
end
|
74
96
|
|
75
|
-
#
|
76
|
-
|
77
|
-
self.send(
|
78
|
-
end
|
79
|
-
|
80
|
-
# t_set_enums
|
81
|
-
define_singleton_method( "t_#{set_name}_#{enum_plural}" ) do
|
82
|
-
send( "t_#{enum_plural}" ).slice( *self.send("#{set_name}_#{enum_plural}") )
|
97
|
+
# class.enum_set_enums_i
|
98
|
+
define_singleton_method( "#{set_name}_#{enum_plural}_i" ) do
|
99
|
+
self.send( "#{enum_plural}" ).slice( *self.send("#{set_name}_#{enum_plural}") ).values
|
83
100
|
end
|
84
101
|
|
85
|
-
#
|
102
|
+
# t_... - are translation dependent methods
|
103
|
+
# class.t_enums_options
|
86
104
|
define_singleton_method( "t_#{set_name}_#{enum_plural}_options" ) do
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
end
|
105
|
+
return [["Enum translations call missed. Did you forget to call translate #{enum_name}"]*2] unless respond_to?( "t_#{enum_plural}_options_raw" )
|
106
|
+
|
107
|
+
send("t_#{enum_plural}_options_raw", send("t_#{set_name}_#{enum_plural}") )
|
91
108
|
end
|
92
109
|
|
93
|
-
#
|
94
|
-
define_singleton_method( "#{set_name}_#{enum_plural}
|
95
|
-
|
110
|
+
# class.t_enums_options_i
|
111
|
+
define_singleton_method( "t_#{set_name}_#{enum_plural}_options_i" ) do
|
112
|
+
return [["Enum translations call missed. Did you forget to call translate #{enum_name}"]*2] unless respond_to?( "t_#{enum_plural}_options_raw_i" )
|
113
|
+
|
114
|
+
send("t_#{enum_plural}_options_raw_i", send("t_#{set_name}_#{enum_plural}") )
|
96
115
|
end
|
97
116
|
|
98
|
-
|
117
|
+
# instance.set_name?
|
118
|
+
define_method "#{set_name}?" do
|
119
|
+
self.send(enum_name) && ( enum_vals.include?( self.send(enum_name) ) || enum_vals.include?( self.send(enum_name).to_sym ))
|
120
|
+
end
|
99
121
|
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
122
|
+
# protected?
|
123
|
+
# class.t_setname_enums ( translations or humanizations subset for a given set )
|
124
|
+
define_singleton_method( "t_#{set_name}_#{enum_plural}" ) do
|
125
|
+
return [(["Enum translations call missed. Did you forget to call translate #{enum_name}"]*2)].to_h unless respond_to?( "t_#{enum_plural}" )
|
104
126
|
|
105
|
-
|
106
|
-
|
107
|
-
|
127
|
+
send( "t_#{enum_plural}" ).slice( *self.send("#{set_name}_#{enum_plural}") )
|
128
|
+
end
|
129
|
+
end
|
108
130
|
end
|
109
131
|
end
|
110
132
|
|
111
133
|
# Ex mass_assign_enum
|
112
|
-
# Used for mass assigning for collection
|
113
|
-
#
|
114
|
-
#
|
115
|
-
# If you need callbacks you can do like this: some_scope.each(&:new_stat!) but if you don't need callbacks and you
|
134
|
+
# Used for mass assigning for collection without callbacks it creates bang methods for collections using update_all.
|
135
|
+
# it's often case when you need bulk update without callbacks, so it's gets frustrating to repeat:
|
136
|
+
# some_scope.update_all(status: Request.statuses[:new_status], update_at: Time.now)
|
137
|
+
# If you need callbacks you can do like this: some_scope.each(&:new_stat!) but if you don't need callbacks and you have lots of records
|
138
|
+
# to change at once you need update_all
|
116
139
|
#
|
117
|
-
#
|
118
|
-
#
|
119
|
-
#
|
120
|
-
#
|
140
|
+
# mass_assign_enum( :status )
|
141
|
+
#
|
142
|
+
# class methods:
|
143
|
+
# in_cart! paid! in_warehouse! and so
|
121
144
|
#
|
122
145
|
# Console:
|
123
146
|
# request1.in_cart!
|
124
147
|
# request2.waiting_for_payment!
|
125
|
-
# Request.
|
126
|
-
# request1.
|
127
|
-
# request2.
|
148
|
+
# Request.with_statuses( :in_cart, :waiting_for_payment ).payed!
|
149
|
+
# request1.paid? # >> true
|
150
|
+
# request2.paid? # >> true
|
128
151
|
# request1.updated_at # >> Time.now
|
129
152
|
# defined?(Request::MassAssignEnum) # >> true
|
130
153
|
#
|
131
|
-
# order.requests.
|
132
|
-
# order.requests.
|
154
|
+
# order.requests.paid.all?(&:paid?) # >> true
|
155
|
+
# order.requests.paid.delivered!
|
133
156
|
# order.requests.map(&:status).uniq #>> [:delivered]
|
134
|
-
#
|
135
|
-
#
|
136
|
-
# Rem:
|
137
|
-
# mass_assign_enum accepts additional options as last argument.
|
138
|
-
# calling mass_assign_enum( :status ) actually is equal to call: mass_assign_enum( :status, { relation: true, association_relation: true } )
|
139
|
-
#
|
140
|
-
# Meaning:
|
141
157
|
|
142
|
-
|
143
|
-
|
144
|
-
# association_relation: true - Order.first.requests.scope.new_stat! - works
|
145
|
-
# but it wouldn't works without 'scope' part! If you want to use it without 'scope' you may do it this way:
|
146
|
-
# class Request
|
147
|
-
# ...
|
148
|
-
# mass_assign_enum( :status, association_relation: false )
|
149
|
-
# end
|
150
|
-
# class Order
|
151
|
-
# has_many :requests, extend: Request::MassAssignEnum
|
152
|
-
# end
|
153
|
-
#
|
154
|
-
# Order.first.requests.respond_to?(:in_cart!) # >> true
|
155
|
-
#
|
156
|
-
# Rem2:
|
157
|
-
# you can mass-assign more than one enum ::MassAssignEnum module will contain mass assign for both. It will break nothing since all enum name must be uniq across model
|
158
|
-
|
159
|
-
def mass_assign_enum( *options )
|
160
|
-
relation_options = (options[-1].is_a?(Hash) && options.pop || {relation: true, association_relation: true} ).with_indifferent_access
|
161
|
-
enums_names = options
|
158
|
+
def mass_assign_enum( *enums_names )
|
162
159
|
enums_names.each do |enum_name|
|
163
160
|
enum_vals = self.send( enum_name.to_s.pluralize )
|
164
161
|
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
enum_vals.keys.each do |enum_el|
|
169
|
-
define_method( "#{enum_el}!" ) do
|
170
|
-
self.update_all( {enum_name => enum_vals[enum_el]}.merge( self.column_names.include?('updated_at') ? {updated_at: Time.now} : {} ))
|
171
|
-
end
|
162
|
+
enum_vals.keys.each do |enum_el|
|
163
|
+
define_singleton_method( "#{enum_el}!" ) do
|
164
|
+
self.update_all( {enum_name => enum_vals[enum_el]}.merge( self.column_names.include?('updated_at') ? {updated_at: Time.now} : {} ))
|
172
165
|
end
|
173
166
|
end
|
174
|
-
self.const_set( :MassAssignEnum, mass_ass_module ) unless defined?(self::MassAssignEnum)
|
175
|
-
|
176
|
-
self::ActiveRecord_Relation.include( self::MassAssignEnum ) if relation_options[:relation]
|
177
|
-
self::ActiveRecord_AssociationRelation.include( self::MassAssignEnum ) if relation_options[:association_relation]
|
178
167
|
end
|
179
168
|
end
|
180
169
|
|
181
|
-
# Ex using localize_enum with Request
|
182
|
-
# class Request
|
183
|
-
#
|
184
170
|
# if app doesn't need internationalization, it may use humanize_enum to make enum user friendly
|
185
|
-
#
|
171
|
+
# class Request
|
186
172
|
# humanize_enum :status, {
|
187
173
|
# #locale dependent example with pluralization and lambda:
|
188
174
|
# payed: -> (t_self) { I18n.t("request.status.payed", count: t_self.sum ) }
|
189
175
|
#
|
190
176
|
# #locale dependent example with pluralization and proc:
|
191
|
-
# payed:
|
177
|
+
# payed: Proc.new{ I18n.t("request.status.payed", count: self.sum ) }
|
192
178
|
#
|
193
179
|
# #locale independent:
|
194
180
|
# ready_for_shipment: "Ready to go!"
|
@@ -200,48 +186,43 @@ module EnumExt
|
|
200
186
|
# humanize_enum :status do
|
201
187
|
# I18n.t("scope.#{status}")
|
202
188
|
# end
|
203
|
-
|
189
|
+
#
|
190
|
+
# in select:
|
191
|
+
# f.select :status, Request.t_statuses_options
|
192
|
+
#
|
193
|
+
# in select in Active Admin filter
|
194
|
+
# collection: Request.t_statuses_options_i
|
195
|
+
#
|
196
|
+
# Rem: select options breaks when using lambda() with params
|
197
|
+
#
|
204
198
|
# Console:
|
205
199
|
# request.sum = 3
|
206
200
|
# request.payed!
|
207
|
-
# request.status
|
208
|
-
# request.t_status
|
201
|
+
# request.status # >> payed
|
202
|
+
# request.t_status # >> "Payed 3 dollars"
|
209
203
|
# Request.t_statuses # >> { in_cart: -> { I18n.t("request.status.in_cart") }, .... }
|
210
|
-
|
211
|
-
# if you need some substitution you can go like this
|
212
|
-
# localize_enum :status, {
|
213
|
-
# ..
|
214
|
-
# delivered: "Delivered at: %{date}"
|
215
|
-
# }
|
216
|
-
# request.delivered!
|
217
|
-
# request.t_status % {date: Time.now.to_s} # >> Delivered at: 05.02.2016
|
218
|
-
#
|
219
|
-
# Using in select:
|
220
|
-
# f.select :status, Request.t_statuses_options
|
221
|
-
#
|
222
|
-
# Rem: select options breaks when using lambda
|
223
|
-
|
224
204
|
def humanize_enum( *args, &block )
|
225
205
|
enum_name = args.shift
|
226
206
|
localizations = args.pop
|
227
|
-
|
207
|
+
enum_plural = enum_name.to_s.pluralize
|
228
208
|
|
229
209
|
self.instance_eval do
|
230
210
|
|
231
211
|
#t_enums
|
232
|
-
define_singleton_method( "t_#{
|
212
|
+
define_singleton_method( "t_#{enum_plural}" ) do
|
233
213
|
# if localization is abscent than block must be given
|
234
214
|
localizations.try(:with_indifferent_access) || localizations ||
|
235
|
-
send(
|
215
|
+
send(enum_plural).keys.map {|en| [en, self.new( {enum_name => en} ).send("t_#{enum_name}")] }.to_h.with_indifferent_access
|
236
216
|
end
|
237
217
|
|
238
218
|
#t_enums_options
|
239
|
-
define_singleton_method( "t_#{
|
240
|
-
send("t_#{
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
219
|
+
define_singleton_method( "t_#{enum_plural}_options" ) do
|
220
|
+
send("t_#{enum_plural}_options_raw", send("t_#{enum_plural}") )
|
221
|
+
end
|
222
|
+
|
223
|
+
#t_enums_options_i
|
224
|
+
define_singleton_method( "t_#{enum_plural}_options_i" ) do
|
225
|
+
send("t_#{enum_plural}_options_raw_i", send("t_#{enum_plural}") )
|
245
226
|
end
|
246
227
|
|
247
228
|
#t_enum
|
@@ -255,6 +236,29 @@ module EnumExt
|
|
255
236
|
t
|
256
237
|
end.to_s
|
257
238
|
end
|
239
|
+
|
240
|
+
#protected?
|
241
|
+
define_singleton_method( "t_#{enum_plural}_options_raw_i" ) do |t_enum_set|
|
242
|
+
send("t_#{enum_plural}_options_raw", t_enum_set ).map do | key_val |
|
243
|
+
key_val[1] = send(enum_plural)[key_val[1]]
|
244
|
+
key_val
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
define_singleton_method( "t_#{enum_plural}_options_raw" ) do |t_enum_set|
|
249
|
+
t_enum_set.invert.to_a.map do | key_val |
|
250
|
+
# since all procs in t_enum are evaluated in context of a record than it's not always possible to create select options
|
251
|
+
if key_val[0].respond_to?(:call)
|
252
|
+
if key_val[0].try(:arity) < 1
|
253
|
+
key_val[0] = key_val[0].try(:call) rescue "Cannot create option for #{key_val[1]} ( proc fails to evaluate )"
|
254
|
+
else
|
255
|
+
key_val[0] = "Cannot create option for #{key_val[1]} because of a lambda"
|
256
|
+
end
|
257
|
+
end
|
258
|
+
key_val
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
258
262
|
end
|
259
263
|
end
|
260
264
|
alias localize_enum humanize_enum
|
@@ -264,33 +268,14 @@ module EnumExt
|
|
264
268
|
# If block is given than no scopes are taken in consider
|
265
269
|
def translate_enum( *args, &block )
|
266
270
|
enum_name = args.shift
|
267
|
-
|
268
|
-
|
269
|
-
translated_enums << enum_name.to_sym
|
271
|
+
enum_plural = enum_name.to_s.pluralize
|
272
|
+
t_scope = args.pop || "activerecord.attributes.#{self.name.underscore}.#{enum_plural}"
|
270
273
|
|
271
274
|
if block_given?
|
272
275
|
humanize_enum( enum_name, &block )
|
273
276
|
else
|
274
|
-
humanize_enum( enum_name, send(
|
277
|
+
humanize_enum( enum_name, send(enum_plural).keys.map{|en| [ en, Proc.new{ I18n.t("#{t_scope}.#{en}") }] }.to_h )
|
275
278
|
end
|
276
|
-
|
277
|
-
end
|
278
|
-
|
279
|
-
# It useful for Active Admin, since it use by default human_attribute_name
|
280
|
-
# to translate or humanize elements, if no translation given.
|
281
|
-
# So when enums translated it breaks default human_attribute_name since it's search I18n scope from
|
282
|
-
def human_attribute_name( name, options = {} )
|
283
|
-
enum_translated?(name) ? super( "t_#{name}", options ) : super( name, options )
|
284
|
-
end
|
285
|
-
|
286
|
-
# helper to determine is attribute is translated enum
|
287
|
-
def enum_translated?( name )
|
288
|
-
translated_enums.include?( name.to_sym )
|
289
|
-
end
|
290
|
-
|
291
|
-
private
|
292
|
-
def translated_enums
|
293
|
-
@translated_enums ||= Set.new
|
294
279
|
end
|
295
280
|
|
296
281
|
end
|
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.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- alekseyl
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-04-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activerecord
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '4.1'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: minitest
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
27
41
|
- !ruby/object:Gem::Dependency
|
28
42
|
name: bundler
|
29
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -52,8 +66,36 @@ dependencies:
|
|
52
66
|
- - "~>"
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '10.0'
|
55
|
-
|
56
|
-
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rails-i18n
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '4'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '4'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: sqlite3
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
description: Enum extension, ads enum sets, mass-assign, localization, and some sugar
|
98
|
+
helpers.
|
57
99
|
email:
|
58
100
|
- leshchuk@gmail.com
|
59
101
|
executables: []
|
@@ -66,6 +108,8 @@ files:
|
|
66
108
|
- LICENSE.txt
|
67
109
|
- README.md
|
68
110
|
- Rakefile
|
111
|
+
- bin/console
|
112
|
+
- bin/setup
|
69
113
|
- enum_ext.gemspec
|
70
114
|
- lib/enum_ext.rb
|
71
115
|
- lib/enum_ext/version.rb
|
@@ -89,8 +133,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
89
133
|
version: '0'
|
90
134
|
requirements: []
|
91
135
|
rubyforge_project:
|
92
|
-
rubygems_version: 2.
|
136
|
+
rubygems_version: 2.6.8
|
93
137
|
signing_key:
|
94
138
|
specification_version: 4
|
95
|
-
summary: Enum extension, ads enum sets, mass-assign
|
139
|
+
summary: Enum extension, ads enum sets, mass-assign, localization, and some sugar
|
140
|
+
helpers.
|
96
141
|
test_files: []
|