enumerize 2.2.1 → 2.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/.github/workflows/ruby.yml +73 -0
- data/CHANGELOG.md +35 -1
- data/Gemfile +2 -3
- data/Gemfile.global +2 -10
- data/Gemfile.mongo_mapper +2 -3
- data/Gemfile.rails60 +6 -0
- data/Gemfile.rails61 +6 -0
- data/Gemfile.rails70 +9 -0
- data/Gemfile.railsmaster +5 -0
- data/README.md +205 -94
- data/Rakefile +2 -0
- data/lib/enumerize/activemodel.rb +2 -0
- data/lib/enumerize/activerecord.rb +36 -2
- data/lib/enumerize/attribute.rb +19 -11
- data/lib/enumerize/attribute_map.rb +2 -0
- data/lib/enumerize/base.rb +6 -6
- data/lib/enumerize/hooks/formtastic.rb +4 -1
- data/lib/enumerize/hooks/sequel_dataset.rb +2 -0
- data/lib/enumerize/hooks/simple_form.rb +4 -1
- data/lib/enumerize/hooks/uniqueness.rb +2 -0
- data/lib/enumerize/integrations/rails_admin.rb +2 -0
- data/lib/enumerize/integrations/rspec/matcher.rb +7 -2
- data/lib/enumerize/integrations/rspec.rb +2 -0
- data/lib/enumerize/module.rb +2 -0
- data/lib/enumerize/module_attributes.rb +2 -0
- data/lib/enumerize/mongoid.rb +16 -0
- data/lib/enumerize/predicatable.rb +3 -1
- data/lib/enumerize/predicates.rb +2 -0
- data/lib/enumerize/scope/activerecord.rb +16 -0
- data/lib/enumerize/scope/mongoid.rb +15 -0
- data/lib/enumerize/scope/sequel.rb +16 -0
- data/lib/enumerize/sequel.rb +9 -4
- data/lib/enumerize/set.rb +2 -0
- data/lib/enumerize/utils.rb +12 -0
- data/lib/enumerize/value.rb +14 -15
- data/lib/enumerize/version.rb +1 -1
- data/lib/enumerize.rb +4 -0
- data/lib/sequel/plugins/enumerize.rb +2 -0
- data/spec/enumerize/integrations/rspec/matcher_spec.rb +13 -10
- data/spec/spec_helper.rb +2 -0
- data/test/activemodel_test.rb +24 -22
- data/test/activerecord_test.rb +229 -92
- data/test/attribute_map_test.rb +9 -7
- data/test/attribute_test.rb +37 -30
- data/test/base_test.rb +38 -36
- data/test/formtastic_test.rb +17 -0
- data/test/module_attributes_test.rb +10 -8
- data/test/mongo_mapper_test.rb +19 -10
- data/test/mongoid_test.rb +51 -22
- data/test/multiple_test.rb +15 -7
- data/test/predicates_test.rb +20 -18
- data/test/rails_admin_test.rb +4 -2
- data/test/sequel_test.rb +100 -47
- data/test/set_test.rb +25 -23
- data/test/simple_form_test.rb +17 -0
- data/test/support/mock_controller.rb +2 -0
- data/test/support/shared_enums.rb +43 -0
- data/test/support/view_test_helper.rb +14 -1
- data/test/test_helper.rb +2 -0
- data/test/value_test.rb +51 -30
- metadata +11 -30
- data/.travis.yml +0 -35
- data/Gemfile.rails42 +0 -7
- data/Gemfile.rails50 +0 -7
- data/Gemfile.rails52 +0 -7
data/README.md
CHANGED
|
@@ -1,7 +1,35 @@
|
|
|
1
|
-
# Enumerize [](http://travis-ci.org/brainspec/enumerize)
|
|
1
|
+
# Enumerize [](http://travis-ci.org/brainspec/enumerize)
|
|
2
2
|
|
|
3
3
|
Enumerated attributes with I18n and ActiveRecord/Mongoid/MongoMapper/Sequel support
|
|
4
4
|
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Installation](#installation)
|
|
8
|
+
- [Supported Versions](#supported-versions)
|
|
9
|
+
- [Usage](#usage)
|
|
10
|
+
- [Database support](#database-support)
|
|
11
|
+
- [ActiveRecord](#activerecord)
|
|
12
|
+
- [Mongoid](#mongoid)
|
|
13
|
+
- [MongoMapper](#mongomapper)
|
|
14
|
+
- [I18n Support](#i18n-support)
|
|
15
|
+
- [I18n Helper Methods](#i18n-helper-methods)
|
|
16
|
+
- [Boolean Helper Methods](#boolean-helper-methods)
|
|
17
|
+
- [Basic](#basic)
|
|
18
|
+
- [Predicate Methods](#predicate-methods)
|
|
19
|
+
- [Optimzations and Tips](#optimzations-and-tips)
|
|
20
|
+
- [Extendable Module](#extendable-module)
|
|
21
|
+
- [Customizing Enumerize Value](#customizing-enumerize-value)
|
|
22
|
+
- [ActiveRecord scopes](#activerecord-scopes)
|
|
23
|
+
- [Array-like Attributes](#array-like-attributes)
|
|
24
|
+
- [Forms](#forms)
|
|
25
|
+
- [SimpleForm](#simpleform)
|
|
26
|
+
- [Formtastic](#formtastic)
|
|
27
|
+
- [Testing](#testing)
|
|
28
|
+
- [RSpec](#rspec)
|
|
29
|
+
- [Minitest with Shoulda](#minitest-with-shoulda)
|
|
30
|
+
- [Other Integrations](#other-integrations)
|
|
31
|
+
- [Contributing](#contributing)
|
|
32
|
+
|
|
5
33
|
## Installation
|
|
6
34
|
|
|
7
35
|
Add this line to your application's Gemfile:
|
|
@@ -17,8 +45,9 @@ Or install it yourself as:
|
|
|
17
45
|
$ gem install enumerize
|
|
18
46
|
|
|
19
47
|
## Supported Versions
|
|
20
|
-
|
|
21
|
-
-
|
|
48
|
+
|
|
49
|
+
- Ruby 2.6+
|
|
50
|
+
- Rails 5.2+
|
|
22
51
|
|
|
23
52
|
## Usage
|
|
24
53
|
|
|
@@ -28,20 +57,23 @@ Basic:
|
|
|
28
57
|
class User
|
|
29
58
|
extend Enumerize
|
|
30
59
|
|
|
31
|
-
enumerize :
|
|
60
|
+
enumerize :role, in: [:user, :admin]
|
|
32
61
|
end
|
|
33
62
|
```
|
|
34
63
|
|
|
35
|
-
Note that enumerized values are just identificators so if you want to use multi-word, etc. values you should use `I18n` feature.
|
|
64
|
+
Note that enumerized values are just identificators so if you want to use multi-word, etc. values then you should use `I18n` feature.
|
|
36
65
|
|
|
66
|
+
---
|
|
37
67
|
|
|
38
|
-
|
|
68
|
+
## Database support
|
|
69
|
+
|
|
70
|
+
### ActiveRecord
|
|
39
71
|
|
|
40
72
|
```ruby
|
|
41
73
|
class CreateUsers < ActiveRecord::Migration
|
|
42
74
|
def change
|
|
43
75
|
create_table :users do |t|
|
|
44
|
-
t.string :
|
|
76
|
+
t.string :status
|
|
45
77
|
t.string :role
|
|
46
78
|
|
|
47
79
|
t.timestamps
|
|
@@ -52,13 +84,25 @@ end
|
|
|
52
84
|
class User < ActiveRecord::Base
|
|
53
85
|
extend Enumerize
|
|
54
86
|
|
|
55
|
-
enumerize :
|
|
87
|
+
enumerize :status, in: [:student, :employed, :retired], default: lambda { |user| StatusIdentifier.status_for_age(user.age).to_sym }
|
|
56
88
|
|
|
57
89
|
enumerize :role, in: [:user, :admin], default: :user
|
|
58
90
|
end
|
|
59
91
|
```
|
|
60
92
|
|
|
61
|
-
|
|
93
|
+
:warning: By default, `enumerize` adds `inclusion` validation to the model. You can skip validations by passing `skip_validations` option. :warning:
|
|
94
|
+
|
|
95
|
+
```ruby
|
|
96
|
+
class User < ActiveRecord::Base
|
|
97
|
+
extend Enumerize
|
|
98
|
+
|
|
99
|
+
enumerize :status, in: [:student, :employed, :retired], skip_validations: lambda { |user| user.new_record? }
|
|
100
|
+
|
|
101
|
+
enumerize :role, in: [:user, :admin], skip_validations: true
|
|
102
|
+
end
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
### Mongoid
|
|
62
106
|
|
|
63
107
|
```ruby
|
|
64
108
|
class User
|
|
@@ -70,7 +114,7 @@ class User
|
|
|
70
114
|
end
|
|
71
115
|
```
|
|
72
116
|
|
|
73
|
-
MongoMapper
|
|
117
|
+
### MongoMapper
|
|
74
118
|
|
|
75
119
|
```ruby
|
|
76
120
|
class User
|
|
@@ -82,50 +126,54 @@ class User
|
|
|
82
126
|
end
|
|
83
127
|
```
|
|
84
128
|
|
|
85
|
-
|
|
129
|
+
---
|
|
130
|
+
|
|
131
|
+
## I18n Support
|
|
86
132
|
|
|
87
133
|
```ruby
|
|
88
134
|
en:
|
|
89
135
|
enumerize:
|
|
90
136
|
user:
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
137
|
+
status:
|
|
138
|
+
student: "Student"
|
|
139
|
+
employed: "Employed"
|
|
140
|
+
retired: "Retiree"
|
|
94
141
|
```
|
|
95
142
|
|
|
96
|
-
or if you use `
|
|
143
|
+
or if you use `status` attribute across several models you can use `defaults` scope:
|
|
97
144
|
|
|
98
145
|
```ruby
|
|
99
146
|
en:
|
|
100
147
|
enumerize:
|
|
101
148
|
defaults:
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
149
|
+
status:
|
|
150
|
+
student: "Student"
|
|
151
|
+
employed: "Employed"
|
|
152
|
+
retired: "Retiree"
|
|
105
153
|
```
|
|
106
154
|
|
|
107
155
|
You can also pass `i18n_scope` option to specify scope (or array of scopes) storing the translations.
|
|
108
156
|
|
|
109
|
-
|
|
110
157
|
```ruby
|
|
111
158
|
class Person
|
|
112
159
|
extend Enumerize
|
|
113
160
|
extend ActiveModel::Naming
|
|
114
161
|
|
|
115
|
-
enumerize :
|
|
116
|
-
enumerize :
|
|
162
|
+
enumerize :status, in: %w[student employed retired], i18n_scope: "status"
|
|
163
|
+
enumerize :roles, in: %w[user admin], i18n_scope: ["user.roles", "roles"]
|
|
117
164
|
end
|
|
118
165
|
|
|
119
166
|
# localization file
|
|
120
167
|
en:
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
168
|
+
status:
|
|
169
|
+
student: "Student"
|
|
170
|
+
employed: "Employed"
|
|
171
|
+
retired: "Retiree"
|
|
172
|
+
user:
|
|
173
|
+
roles:
|
|
174
|
+
user: "User"
|
|
175
|
+
roles:
|
|
176
|
+
admin: "Admin"
|
|
129
177
|
```
|
|
130
178
|
|
|
131
179
|
Note that if you want to use I18n feature with plain Ruby object don't forget to extend it with `ActiveModel::Naming`:
|
|
@@ -137,88 +185,120 @@ class User
|
|
|
137
185
|
end
|
|
138
186
|
```
|
|
139
187
|
|
|
140
|
-
|
|
188
|
+
### I18n Helper Methods
|
|
189
|
+
|
|
190
|
+
#### \*\_text / .text
|
|
191
|
+
|
|
192
|
+
Attribute's I18n text value:
|
|
193
|
+
|
|
194
|
+
```ruby
|
|
195
|
+
@user.status_text # or @user.status.text
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
#### values
|
|
199
|
+
|
|
200
|
+
List of possible values for an enumerized attribute:
|
|
141
201
|
|
|
142
202
|
```ruby
|
|
143
|
-
|
|
203
|
+
User.status.values # or User.enumerized_attributes[:status].values
|
|
204
|
+
# => ['student', 'employed', 'retired']
|
|
144
205
|
```
|
|
145
206
|
|
|
146
|
-
|
|
207
|
+
#### I18n text values
|
|
208
|
+
|
|
209
|
+
List of possible I18n text values for an enumerized attribute:
|
|
147
210
|
|
|
148
211
|
```ruby
|
|
149
|
-
User.
|
|
212
|
+
User.status.values.collect(&:text)
|
|
213
|
+
# => ['Student', 'Employed', 'Retiree']
|
|
150
214
|
```
|
|
151
215
|
|
|
152
|
-
|
|
216
|
+
#### Form example
|
|
217
|
+
|
|
218
|
+
Use it with forms (it supports `:only` and `:except` options):
|
|
153
219
|
|
|
154
220
|
```erb
|
|
155
221
|
<%= form_for @user do |f| %>
|
|
156
|
-
<%= f.select :
|
|
222
|
+
<%= f.select :status, User.status.options %>
|
|
157
223
|
<% end %>
|
|
158
224
|
```
|
|
159
225
|
|
|
160
|
-
|
|
226
|
+
---
|
|
227
|
+
|
|
228
|
+
## Boolean Helper Methods
|
|
229
|
+
|
|
230
|
+
### Basic
|
|
161
231
|
|
|
162
232
|
```ruby
|
|
163
|
-
user.
|
|
164
|
-
user.
|
|
165
|
-
user.
|
|
233
|
+
user.status = :student
|
|
234
|
+
user.status.student? #=> true
|
|
235
|
+
user.status.retired? #=> false
|
|
166
236
|
```
|
|
167
237
|
|
|
168
|
-
Predicate
|
|
238
|
+
### Predicate Methods
|
|
169
239
|
|
|
170
240
|
```ruby
|
|
171
241
|
class User
|
|
172
242
|
extend Enumerize
|
|
173
243
|
|
|
174
|
-
enumerize :
|
|
244
|
+
enumerize :status, in: %w(student employed retired), predicates: true
|
|
175
245
|
end
|
|
176
246
|
|
|
177
247
|
user = User.new
|
|
178
248
|
|
|
179
|
-
user.
|
|
180
|
-
user.
|
|
249
|
+
user.student? # => false
|
|
250
|
+
user.employed? # => false
|
|
181
251
|
|
|
182
|
-
user.
|
|
252
|
+
user.status = :student
|
|
183
253
|
|
|
184
|
-
user.
|
|
185
|
-
user.
|
|
254
|
+
user.student? # => true
|
|
255
|
+
user.employed? # => false
|
|
186
256
|
```
|
|
257
|
+
|
|
187
258
|
:warning: If `enumerize` is used with Mongoid, it's not recommended to use `"writer"` as a field value since `writer?` is defined by Mongoid. [See more](https://github.com/brainspec/enumerize/issues/235). :warning:
|
|
188
259
|
|
|
189
|
-
|
|
260
|
+
#### Predicate Prefixes
|
|
190
261
|
|
|
191
262
|
```ruby
|
|
192
263
|
class User
|
|
193
264
|
extend Enumerize
|
|
194
265
|
|
|
195
|
-
enumerize :
|
|
266
|
+
enumerize :status, in: %w(student employed retired), predicates: { prefix: true }
|
|
196
267
|
end
|
|
197
268
|
|
|
198
269
|
user = User.new
|
|
199
|
-
user.
|
|
200
|
-
user.
|
|
270
|
+
user.status = 'student'
|
|
271
|
+
user.status_student? # => true
|
|
201
272
|
```
|
|
273
|
+
|
|
202
274
|
Use `:only` and `:except` options to specify what values create predicate methods for.
|
|
203
275
|
|
|
276
|
+
---
|
|
277
|
+
|
|
278
|
+
## Optimzations and Tips
|
|
279
|
+
|
|
280
|
+
### Extendable Module
|
|
281
|
+
|
|
204
282
|
To make some attributes shared across different classes it's possible to define them in a separate module and then include it into classes:
|
|
205
283
|
|
|
206
284
|
```ruby
|
|
207
|
-
module
|
|
285
|
+
module RoleEnumerations
|
|
208
286
|
extend Enumerize
|
|
209
287
|
|
|
210
|
-
enumerize :
|
|
288
|
+
enumerize :roles, in: %w[user admin]
|
|
211
289
|
end
|
|
212
290
|
|
|
213
|
-
class
|
|
214
|
-
include
|
|
291
|
+
class Buyer
|
|
292
|
+
include RoleEnumerations
|
|
215
293
|
end
|
|
216
294
|
|
|
217
|
-
class
|
|
218
|
-
include
|
|
295
|
+
class Seller
|
|
296
|
+
include RoleEnumerations
|
|
219
297
|
end
|
|
220
298
|
```
|
|
221
299
|
|
|
300
|
+
### Customizing Enumerize Value
|
|
301
|
+
|
|
222
302
|
It's also possible to store enumerized attribute value using custom values (e.g. integers). You can pass a hash as `:in` option to achieve this:
|
|
223
303
|
|
|
224
304
|
```ruby
|
|
@@ -237,27 +317,49 @@ User.role.find_value(:user).value #=> 1
|
|
|
237
317
|
User.role.find_value(:admin).value #=> 2
|
|
238
318
|
```
|
|
239
319
|
|
|
240
|
-
ActiveRecord scopes:
|
|
320
|
+
### ActiveRecord scopes:
|
|
321
|
+
|
|
322
|
+
#### Basic
|
|
241
323
|
|
|
242
324
|
```ruby
|
|
243
325
|
class User < ActiveRecord::Base
|
|
244
326
|
extend Enumerize
|
|
245
|
-
enumerize :
|
|
246
|
-
enumerize :status, :in => {
|
|
327
|
+
enumerize :role, :in => [:user, :admin], scope: true
|
|
328
|
+
enumerize :status, :in => { student: 1, employed: 2, retired: 3 }, scope: :having_status
|
|
247
329
|
end
|
|
248
330
|
|
|
249
|
-
User.
|
|
250
|
-
# SELECT "users".* FROM "users" WHERE "users"."
|
|
331
|
+
User.with_role(:admin)
|
|
332
|
+
# SELECT "users".* FROM "users" WHERE "users"."role" IN ('admin')
|
|
251
333
|
|
|
252
|
-
User.
|
|
253
|
-
# SELECT "users".* FROM "users" WHERE "users"."
|
|
334
|
+
User.without_role(:admin)
|
|
335
|
+
# SELECT "users".* FROM "users" WHERE "users"."role" NOT IN ('admin')
|
|
254
336
|
|
|
255
|
-
User.having_status(:
|
|
256
|
-
# SELECT "users".* FROM "users" WHERE "users"."status" IN (2) AND "users"."
|
|
337
|
+
User.having_status(:employed).with_role(:user, :admin)
|
|
338
|
+
# SELECT "users".* FROM "users" WHERE "users"."status" IN (2) AND "users"."role" IN ('user', 'admin')
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
#### Shallow Scopes
|
|
342
|
+
|
|
343
|
+
Adds named scopes to the class directly.
|
|
344
|
+
|
|
345
|
+
```ruby
|
|
346
|
+
class User < ActiveRecord::Base
|
|
347
|
+
extend Enumerize
|
|
348
|
+
enumerize :status, :in => [:student, :employed, :retired], scope: :shallow
|
|
349
|
+
enumerize :role, :in => { user: 1, admin: 2 }, scope: :shallow
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
User.student
|
|
353
|
+
# SELECT "users".* FROM "users" WHERE "users"."status" = 'student'
|
|
354
|
+
|
|
355
|
+
User.admin
|
|
356
|
+
# SELECT "users".* FROM "users" WHERE "users"."role" = 2
|
|
257
357
|
```
|
|
258
358
|
|
|
259
359
|
:warning: It is not possible to define a scope when using the `:multiple` option. :warning:
|
|
260
360
|
|
|
361
|
+
### Array-like Attributes
|
|
362
|
+
|
|
261
363
|
Array-like attributes with plain ruby objects:
|
|
262
364
|
|
|
263
365
|
```ruby
|
|
@@ -292,22 +394,26 @@ get an array of all text values:
|
|
|
292
394
|
Also, the reader method can be overridden, referencing the enumerized attribute value using `super`:
|
|
293
395
|
|
|
294
396
|
```ruby
|
|
295
|
-
def
|
|
397
|
+
def status
|
|
296
398
|
if current_user.admin?
|
|
297
|
-
"Super#{super}"
|
|
399
|
+
"Super #{super}"
|
|
298
400
|
else
|
|
299
401
|
super
|
|
300
402
|
end
|
|
301
403
|
end
|
|
302
404
|
```
|
|
303
405
|
|
|
406
|
+
---
|
|
407
|
+
|
|
408
|
+
## Forms
|
|
409
|
+
|
|
304
410
|
### SimpleForm
|
|
305
411
|
|
|
306
412
|
If you are using SimpleForm gem you don't need to specify input type (`:select` by default) and collection:
|
|
307
413
|
|
|
308
414
|
```erb
|
|
309
415
|
<%= simple_form_for @user do |f| %>
|
|
310
|
-
<%= f.input :
|
|
416
|
+
<%= f.input :status %>
|
|
311
417
|
<% end %>
|
|
312
418
|
```
|
|
313
419
|
|
|
@@ -315,7 +421,7 @@ and if you want it as radio buttons:
|
|
|
315
421
|
|
|
316
422
|
```erb
|
|
317
423
|
<%= simple_form_for @user do |f| %>
|
|
318
|
-
<%= f.input :
|
|
424
|
+
<%= f.input :status, :as => :radio_buttons %>
|
|
319
425
|
<% end %>
|
|
320
426
|
```
|
|
321
427
|
|
|
@@ -327,7 +433,7 @@ If you are using Formtastic gem you also don't need to specify input type (`:sel
|
|
|
327
433
|
|
|
328
434
|
```erb
|
|
329
435
|
<%= semantic_form_for @user do |f| %>
|
|
330
|
-
<%= f.input :
|
|
436
|
+
<%= f.input :status %>
|
|
331
437
|
<% end %>
|
|
332
438
|
```
|
|
333
439
|
|
|
@@ -335,10 +441,14 @@ and if you want it as radio buttons:
|
|
|
335
441
|
|
|
336
442
|
```erb
|
|
337
443
|
<%= semantic_form_for @user do |f| %>
|
|
338
|
-
<%= f.input :
|
|
444
|
+
<%= f.input :status, :as => :radio %>
|
|
339
445
|
<% end %>
|
|
340
446
|
```
|
|
341
447
|
|
|
448
|
+
---
|
|
449
|
+
|
|
450
|
+
## Testing
|
|
451
|
+
|
|
342
452
|
### RSpec
|
|
343
453
|
|
|
344
454
|
Also you can use builtin RSpec matcher:
|
|
@@ -347,14 +457,14 @@ Also you can use builtin RSpec matcher:
|
|
|
347
457
|
class User
|
|
348
458
|
extend Enumerize
|
|
349
459
|
|
|
350
|
-
enumerize :
|
|
460
|
+
enumerize :status, in: [:student, :employed, :retired]
|
|
351
461
|
end
|
|
352
462
|
|
|
353
463
|
describe User do
|
|
354
|
-
it { should enumerize(:
|
|
464
|
+
it { should enumerize(:status) }
|
|
355
465
|
|
|
356
466
|
# or with RSpec 3 expect syntax
|
|
357
|
-
it { is_expected.to enumerize(:
|
|
467
|
+
it { is_expected.to enumerize(:status) }
|
|
358
468
|
end
|
|
359
469
|
```
|
|
360
470
|
|
|
@@ -368,11 +478,11 @@ Use `in` to test usage of the `:in` option.
|
|
|
368
478
|
class User
|
|
369
479
|
extend Enumerize
|
|
370
480
|
|
|
371
|
-
enumerize :
|
|
481
|
+
enumerize :status, in: [:student, :employed, :retired]
|
|
372
482
|
end
|
|
373
483
|
|
|
374
484
|
describe User do
|
|
375
|
-
it { should enumerize(:
|
|
485
|
+
it { should enumerize(:status).in(:student, :employed, :retired) }
|
|
376
486
|
end
|
|
377
487
|
```
|
|
378
488
|
|
|
@@ -383,11 +493,11 @@ qualifier.
|
|
|
383
493
|
class User
|
|
384
494
|
extend Enumerize
|
|
385
495
|
|
|
386
|
-
enumerize :
|
|
496
|
+
enumerize :role, in: { user: 0, admin: 1 }
|
|
387
497
|
end
|
|
388
498
|
|
|
389
499
|
describe User do
|
|
390
|
-
it { should enumerize(:
|
|
500
|
+
it { should enumerize(:role).in(user: 0, admin: 1) }
|
|
391
501
|
end
|
|
392
502
|
```
|
|
393
503
|
|
|
@@ -399,11 +509,11 @@ Use `with_default` to test usage of the `:default` option.
|
|
|
399
509
|
class User
|
|
400
510
|
extend Enumerize
|
|
401
511
|
|
|
402
|
-
enumerize :
|
|
512
|
+
enumerize :role, in: [:user, :admin], default: :user
|
|
403
513
|
end
|
|
404
514
|
|
|
405
515
|
describe User do
|
|
406
|
-
it { should enumerize(:
|
|
516
|
+
it { should enumerize(:user).in(:user, :admin).with_default(:user) }
|
|
407
517
|
end
|
|
408
518
|
```
|
|
409
519
|
|
|
@@ -415,11 +525,11 @@ Use `with_i18n_scope` to test usage of the `:i18n_scope` option.
|
|
|
415
525
|
class User
|
|
416
526
|
extend Enumerize
|
|
417
527
|
|
|
418
|
-
enumerize :
|
|
528
|
+
enumerize :status, in: [:student, :employed, :retired], i18n_scope: 'status'
|
|
419
529
|
end
|
|
420
530
|
|
|
421
531
|
describe User do
|
|
422
|
-
it { should enumerize(:
|
|
532
|
+
it { should enumerize(:status).in(:student, :employed, :retired).with_i18n_scope('status') }
|
|
423
533
|
end
|
|
424
534
|
```
|
|
425
535
|
|
|
@@ -431,11 +541,11 @@ Use `with_predicates` to test usage of the `:predicates` option.
|
|
|
431
541
|
class User
|
|
432
542
|
extend Enumerize
|
|
433
543
|
|
|
434
|
-
enumerize :
|
|
544
|
+
enumerize :status, in: [:student, :employed, :retired], predicates: true
|
|
435
545
|
end
|
|
436
546
|
|
|
437
547
|
describe User do
|
|
438
|
-
it { should enumerize(:
|
|
548
|
+
it { should enumerize(:status).in(:student, :employed, :retired).with_predicates(true) }
|
|
439
549
|
end
|
|
440
550
|
```
|
|
441
551
|
|
|
@@ -445,11 +555,11 @@ You can text prefixed predicates with the `with_predicates` qualifiers.
|
|
|
445
555
|
class User
|
|
446
556
|
extend Enumerize
|
|
447
557
|
|
|
448
|
-
enumerize :
|
|
558
|
+
enumerize :status, in: [:student, :employed, :retired], predicates: { prefix: true }
|
|
449
559
|
end
|
|
450
560
|
|
|
451
561
|
describe User do
|
|
452
|
-
it { should enumerize(:
|
|
562
|
+
it { should enumerize(:status).in(:student, :employed, :retired).with_predicates(prefix: true) }
|
|
453
563
|
end
|
|
454
564
|
```
|
|
455
565
|
|
|
@@ -461,25 +571,25 @@ Use `with_scope` to test usage of the `:scope` option.
|
|
|
461
571
|
class User
|
|
462
572
|
extend Enumerize
|
|
463
573
|
|
|
464
|
-
enumerize :
|
|
574
|
+
enumerize :status, in: [:student, :employed, :retired], scope: true
|
|
465
575
|
end
|
|
466
576
|
|
|
467
577
|
describe User do
|
|
468
|
-
it { should enumerize(:
|
|
578
|
+
it { should enumerize(:status).in(:student, :employed, :retired).with_scope(true) }
|
|
469
579
|
end
|
|
470
580
|
```
|
|
471
581
|
|
|
472
|
-
You can
|
|
582
|
+
You can test a custom scope with the `with_scope` qualifiers.
|
|
473
583
|
|
|
474
584
|
```ruby
|
|
475
585
|
class User
|
|
476
586
|
extend Enumerize
|
|
477
587
|
|
|
478
|
-
enumerize :
|
|
588
|
+
enumerize :status, in: [:student, :employed], scope: :employable
|
|
479
589
|
end
|
|
480
590
|
|
|
481
591
|
describe User do
|
|
482
|
-
it { should enumerize(:
|
|
592
|
+
it { should enumerize(:status).in(:student, :employed, :retired).with_scope(scope: :employable) }
|
|
483
593
|
end
|
|
484
594
|
```
|
|
485
595
|
|
|
@@ -491,11 +601,11 @@ Use `with_multiple` to test usage of the `:multiple` option.
|
|
|
491
601
|
class User
|
|
492
602
|
extend Enumerize
|
|
493
603
|
|
|
494
|
-
enumerize :
|
|
604
|
+
enumerize :status, in: [:student, :employed, :retired], multiple: true
|
|
495
605
|
end
|
|
496
606
|
|
|
497
607
|
describe User do
|
|
498
|
-
it { should enumerize(:
|
|
608
|
+
it { should enumerize(:status).in(:student, :employed, :retired).with_multiple(true) }
|
|
499
609
|
end
|
|
500
610
|
```
|
|
501
611
|
|
|
@@ -518,8 +628,9 @@ end
|
|
|
518
628
|
|
|
519
629
|
Enumerize integrates with the following automatically:
|
|
520
630
|
|
|
521
|
-
|
|
631
|
+
- [RailsAdmin](https://github.com/sferik/rails_admin/)
|
|
522
632
|
|
|
633
|
+
---
|
|
523
634
|
|
|
524
635
|
## Contributing
|
|
525
636
|
|
data/Rakefile
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module Enumerize
|
|
2
4
|
module ActiveRecordSupport
|
|
3
5
|
def enumerize(name, options={})
|
|
@@ -19,8 +21,18 @@ module Enumerize
|
|
|
19
21
|
require 'enumerize/hooks/uniqueness'
|
|
20
22
|
|
|
21
23
|
unless options[:multiple]
|
|
22
|
-
|
|
23
|
-
|
|
24
|
+
if ::ActiveRecord.version >= ::Gem::Version.new("7.0.0.alpha")
|
|
25
|
+
attribute(name) do |subtype|
|
|
26
|
+
Type.new(enumerized_attributes[name], subtype)
|
|
27
|
+
end
|
|
28
|
+
elsif ::ActiveRecord.version >= ::Gem::Version.new("6.1.0.alpha")
|
|
29
|
+
decorate_attribute_type(name.to_s) do |subtype|
|
|
30
|
+
Type.new(enumerized_attributes[name], subtype)
|
|
31
|
+
end
|
|
32
|
+
else
|
|
33
|
+
decorate_attribute_type(name, :enumerize) do |subtype|
|
|
34
|
+
Type.new(enumerized_attributes[name], subtype)
|
|
35
|
+
end
|
|
24
36
|
end
|
|
25
37
|
end
|
|
26
38
|
end
|
|
@@ -50,6 +62,28 @@ module Enumerize
|
|
|
50
62
|
|
|
51
63
|
became
|
|
52
64
|
end
|
|
65
|
+
|
|
66
|
+
def reload(options = nil)
|
|
67
|
+
reloaded = super
|
|
68
|
+
|
|
69
|
+
reloaded.class.enumerized_attributes.each do |attr|
|
|
70
|
+
begin
|
|
71
|
+
# Checks first if the enumerized attribute is in ActiveRecord::Store
|
|
72
|
+
store_attr, _ = reloaded.class.stored_attributes.detect do |_store_attr, keys|
|
|
73
|
+
keys.include?(attr.name)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
if store_attr.present?
|
|
77
|
+
reloaded.send("#{attr.name}=", reloaded.send(store_attr).with_indifferent_access[attr.name])
|
|
78
|
+
else
|
|
79
|
+
reloaded.send("#{attr.name}=", reloaded[attr.name])
|
|
80
|
+
end
|
|
81
|
+
rescue ActiveModel::MissingAttributeError
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
reloaded
|
|
86
|
+
end
|
|
53
87
|
end
|
|
54
88
|
|
|
55
89
|
module RelationMethods
|