careacademy-enumerize 2.8.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 +7 -0
- data/.github/workflows/ruby.yml +69 -0
- data/.gitignore +23 -0
- data/.rspec +2 -0
- data/CHANGELOG.md +327 -0
- data/Gemfile +6 -0
- data/Gemfile.global +12 -0
- data/Gemfile.mongo_mapper +6 -0
- data/Gemfile.rails60 +6 -0
- data/Gemfile.rails61 +6 -0
- data/Gemfile.rails70 +9 -0
- data/Gemfile.railsmaster +5 -0
- data/MIT-LICENSE +22 -0
- data/README.md +641 -0
- data/Rakefile +17 -0
- data/enumerize.gemspec +22 -0
- data/lib/enumerize/activemodel.rb +47 -0
- data/lib/enumerize/activerecord.rb +142 -0
- data/lib/enumerize/attribute.rb +192 -0
- data/lib/enumerize/attribute_map.rb +40 -0
- data/lib/enumerize/base.rb +112 -0
- data/lib/enumerize/hooks/formtastic.rb +27 -0
- data/lib/enumerize/hooks/sequel_dataset.rb +17 -0
- data/lib/enumerize/hooks/simple_form.rb +37 -0
- data/lib/enumerize/hooks/uniqueness.rb +22 -0
- data/lib/enumerize/integrations/rails_admin.rb +18 -0
- data/lib/enumerize/integrations/rspec/matcher.rb +164 -0
- data/lib/enumerize/integrations/rspec.rb +19 -0
- data/lib/enumerize/module.rb +33 -0
- data/lib/enumerize/module_attributes.rb +12 -0
- data/lib/enumerize/mongoid.rb +29 -0
- data/lib/enumerize/predicatable.rb +23 -0
- data/lib/enumerize/predicates.rb +76 -0
- data/lib/enumerize/scope/activerecord.rb +53 -0
- data/lib/enumerize/scope/mongoid.rb +50 -0
- data/lib/enumerize/scope/sequel.rb +56 -0
- data/lib/enumerize/sequel.rb +62 -0
- data/lib/enumerize/set.rb +81 -0
- data/lib/enumerize/utils.rb +12 -0
- data/lib/enumerize/value.rb +47 -0
- data/lib/enumerize/version.rb +5 -0
- data/lib/enumerize.rb +90 -0
- data/lib/sequel/plugins/enumerize.rb +18 -0
- data/spec/enumerize/integrations/rspec/matcher_spec.rb +261 -0
- data/spec/spec_helper.rb +30 -0
- data/test/activemodel_test.rb +114 -0
- data/test/activerecord_test.rb +679 -0
- data/test/attribute_map_test.rb +70 -0
- data/test/attribute_test.rb +141 -0
- data/test/base_test.rb +230 -0
- data/test/formtastic_test.rb +152 -0
- data/test/module_attributes_test.rb +52 -0
- data/test/mongo_mapper_test.rb +83 -0
- data/test/mongoid_test.rb +164 -0
- data/test/multiple_test.rb +65 -0
- data/test/predicates_test.rb +65 -0
- data/test/rails_admin_test.rb +27 -0
- data/test/sequel_test.rb +344 -0
- data/test/set_test.rb +166 -0
- data/test/simple_form_test.rb +156 -0
- data/test/support/mock_controller.rb +31 -0
- data/test/support/shared_enums.rb +43 -0
- data/test/support/view_test_helper.rb +46 -0
- data/test/test_helper.rb +53 -0
- data/test/value_test.rb +158 -0
- metadata +143 -0
data/README.md
ADDED
@@ -0,0 +1,641 @@
|
|
1
|
+
# Enumerize [](http://travis-ci.org/brainspec/enumerize)
|
2
|
+
|
3
|
+
Enumerated attributes with I18n and ActiveRecord/Mongoid/MongoMapper/Sequel support
|
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
|
+
|
33
|
+
## Installation
|
34
|
+
|
35
|
+
Add this line to your application's Gemfile:
|
36
|
+
|
37
|
+
gem 'enumerize'
|
38
|
+
|
39
|
+
And then execute:
|
40
|
+
|
41
|
+
$ bundle
|
42
|
+
|
43
|
+
Or install it yourself as:
|
44
|
+
|
45
|
+
$ gem install enumerize
|
46
|
+
|
47
|
+
## Supported Versions
|
48
|
+
|
49
|
+
- Ruby 2.7+
|
50
|
+
- Rails 5.2+
|
51
|
+
|
52
|
+
## Usage
|
53
|
+
|
54
|
+
Basic:
|
55
|
+
|
56
|
+
```ruby
|
57
|
+
class User
|
58
|
+
extend Enumerize
|
59
|
+
|
60
|
+
enumerize :role, in: [:user, :admin]
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
Note that enumerized values are just identificators so if you want to use multi-word, etc. values then you should use `I18n` feature.
|
65
|
+
|
66
|
+
---
|
67
|
+
|
68
|
+
## Database support
|
69
|
+
|
70
|
+
### ActiveRecord
|
71
|
+
|
72
|
+
```ruby
|
73
|
+
class CreateUsers < ActiveRecord::Migration
|
74
|
+
def change
|
75
|
+
create_table :users do |t|
|
76
|
+
t.string :status
|
77
|
+
t.string :role
|
78
|
+
|
79
|
+
t.timestamps
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class User < ActiveRecord::Base
|
85
|
+
extend Enumerize
|
86
|
+
|
87
|
+
enumerize :status, in: [:student, :employed, :retired], default: lambda { |user| StatusIdentifier.status_for_age(user.age).to_sym }
|
88
|
+
|
89
|
+
enumerize :role, in: [:user, :admin], default: :user
|
90
|
+
end
|
91
|
+
```
|
92
|
+
|
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
|
106
|
+
|
107
|
+
```ruby
|
108
|
+
class User
|
109
|
+
include Mongoid::Document
|
110
|
+
extend Enumerize
|
111
|
+
|
112
|
+
field :role
|
113
|
+
enumerize :role, in: [:user, :admin], default: :user
|
114
|
+
end
|
115
|
+
```
|
116
|
+
|
117
|
+
### MongoMapper
|
118
|
+
|
119
|
+
```ruby
|
120
|
+
class User
|
121
|
+
include MongoMapper::Document
|
122
|
+
extend Enumerize
|
123
|
+
|
124
|
+
key :role
|
125
|
+
enumerize :role, in: [:user, :admin], default: :user
|
126
|
+
end
|
127
|
+
```
|
128
|
+
|
129
|
+
---
|
130
|
+
|
131
|
+
## I18n Support
|
132
|
+
|
133
|
+
```ruby
|
134
|
+
en:
|
135
|
+
enumerize:
|
136
|
+
user:
|
137
|
+
status:
|
138
|
+
student: "Student"
|
139
|
+
employed: "Employed"
|
140
|
+
retired: "Retiree"
|
141
|
+
```
|
142
|
+
|
143
|
+
or if you use `status` attribute across several models you can use `defaults` scope:
|
144
|
+
|
145
|
+
```ruby
|
146
|
+
en:
|
147
|
+
enumerize:
|
148
|
+
defaults:
|
149
|
+
status:
|
150
|
+
student: "Student"
|
151
|
+
employed: "Employed"
|
152
|
+
retired: "Retiree"
|
153
|
+
```
|
154
|
+
|
155
|
+
You can also pass `i18n_scope` option to specify scope (or array of scopes) storing the translations.
|
156
|
+
|
157
|
+
```ruby
|
158
|
+
class Person
|
159
|
+
extend Enumerize
|
160
|
+
extend ActiveModel::Naming
|
161
|
+
|
162
|
+
enumerize :status, in: %w[student employed retired], i18n_scope: "status"
|
163
|
+
enumerize :roles, in: %w[user admin], i18n_scope: ["user.roles", "roles"]
|
164
|
+
end
|
165
|
+
|
166
|
+
# localization file
|
167
|
+
en:
|
168
|
+
status:
|
169
|
+
student: "Student"
|
170
|
+
employed: "Employed"
|
171
|
+
retired: "Retiree"
|
172
|
+
user:
|
173
|
+
roles:
|
174
|
+
user: "User"
|
175
|
+
roles:
|
176
|
+
admin: "Admin"
|
177
|
+
```
|
178
|
+
|
179
|
+
Note that if you want to use I18n feature with plain Ruby object don't forget to extend it with `ActiveModel::Naming`:
|
180
|
+
|
181
|
+
```ruby
|
182
|
+
class User
|
183
|
+
extend Enumerize
|
184
|
+
extend ActiveModel::Naming
|
185
|
+
end
|
186
|
+
```
|
187
|
+
|
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:
|
201
|
+
|
202
|
+
```ruby
|
203
|
+
User.status.values # or User.enumerized_attributes[:status].values
|
204
|
+
# => ['student', 'employed', 'retired']
|
205
|
+
```
|
206
|
+
|
207
|
+
#### I18n text values
|
208
|
+
|
209
|
+
List of possible I18n text values for an enumerized attribute:
|
210
|
+
|
211
|
+
```ruby
|
212
|
+
User.status.values.collect(&:text)
|
213
|
+
# => ['Student', 'Employed', 'Retiree']
|
214
|
+
```
|
215
|
+
|
216
|
+
#### Form example
|
217
|
+
|
218
|
+
Use it with forms (it supports `:only` and `:except` options):
|
219
|
+
|
220
|
+
```erb
|
221
|
+
<%= form_for @user do |f| %>
|
222
|
+
<%= f.select :status, User.status.options %>
|
223
|
+
<% end %>
|
224
|
+
```
|
225
|
+
|
226
|
+
---
|
227
|
+
|
228
|
+
## Boolean Helper Methods
|
229
|
+
|
230
|
+
### Basic
|
231
|
+
|
232
|
+
```ruby
|
233
|
+
user.status = :student
|
234
|
+
user.status.student? #=> true
|
235
|
+
user.status.retired? #=> false
|
236
|
+
```
|
237
|
+
|
238
|
+
### Predicate Methods
|
239
|
+
|
240
|
+
```ruby
|
241
|
+
class User
|
242
|
+
extend Enumerize
|
243
|
+
|
244
|
+
enumerize :status, in: %w(student employed retired), predicates: true
|
245
|
+
end
|
246
|
+
|
247
|
+
user = User.new
|
248
|
+
|
249
|
+
user.student? # => false
|
250
|
+
user.employed? # => false
|
251
|
+
|
252
|
+
user.status = :student
|
253
|
+
|
254
|
+
user.student? # => true
|
255
|
+
user.employed? # => false
|
256
|
+
```
|
257
|
+
|
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:
|
259
|
+
|
260
|
+
#### Predicate Prefixes
|
261
|
+
|
262
|
+
```ruby
|
263
|
+
class User
|
264
|
+
extend Enumerize
|
265
|
+
|
266
|
+
enumerize :status, in: %w(student employed retired), predicates: { prefix: true }
|
267
|
+
end
|
268
|
+
|
269
|
+
user = User.new
|
270
|
+
user.status = 'student'
|
271
|
+
user.status_student? # => true
|
272
|
+
```
|
273
|
+
|
274
|
+
Use `:only` and `:except` options to specify what values create predicate methods for.
|
275
|
+
|
276
|
+
---
|
277
|
+
|
278
|
+
## Optimzations and Tips
|
279
|
+
|
280
|
+
### Extendable Module
|
281
|
+
|
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:
|
283
|
+
|
284
|
+
```ruby
|
285
|
+
module RoleEnumerations
|
286
|
+
extend Enumerize
|
287
|
+
|
288
|
+
enumerize :roles, in: %w[user admin]
|
289
|
+
end
|
290
|
+
|
291
|
+
class Buyer
|
292
|
+
include RoleEnumerations
|
293
|
+
end
|
294
|
+
|
295
|
+
class Seller
|
296
|
+
include RoleEnumerations
|
297
|
+
end
|
298
|
+
```
|
299
|
+
|
300
|
+
### Customizing Enumerize Value
|
301
|
+
|
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:
|
303
|
+
|
304
|
+
```ruby
|
305
|
+
class User < ActiveRecord::Base
|
306
|
+
extend Enumerize
|
307
|
+
|
308
|
+
enumerize :role, in: {:user => 1, :admin => 2}
|
309
|
+
end
|
310
|
+
|
311
|
+
user = User.new
|
312
|
+
user.role = :user
|
313
|
+
user.role #=> 'user'
|
314
|
+
user.role_value #=> 1
|
315
|
+
|
316
|
+
User.role.find_value(:user).value #=> 1
|
317
|
+
User.role.find_value(:admin).value #=> 2
|
318
|
+
```
|
319
|
+
|
320
|
+
### ActiveRecord scopes:
|
321
|
+
|
322
|
+
#### Basic
|
323
|
+
|
324
|
+
```ruby
|
325
|
+
class User < ActiveRecord::Base
|
326
|
+
extend Enumerize
|
327
|
+
enumerize :role, :in => [:user, :admin], scope: true
|
328
|
+
enumerize :status, :in => { student: 1, employed: 2, retired: 3 }, scope: :having_status
|
329
|
+
end
|
330
|
+
|
331
|
+
User.with_role(:admin)
|
332
|
+
# SELECT "users".* FROM "users" WHERE "users"."role" IN ('admin')
|
333
|
+
|
334
|
+
User.without_role(:admin)
|
335
|
+
# SELECT "users".* FROM "users" WHERE "users"."role" NOT IN ('admin')
|
336
|
+
|
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
|
357
|
+
```
|
358
|
+
|
359
|
+
:warning: It is not possible to define a scope when using the `:multiple` option. :warning:
|
360
|
+
|
361
|
+
### Array-like Attributes
|
362
|
+
|
363
|
+
Array-like attributes with plain ruby objects:
|
364
|
+
|
365
|
+
```ruby
|
366
|
+
class User
|
367
|
+
extend Enumerize
|
368
|
+
|
369
|
+
enumerize :interests, in: [:music, :sports], multiple: true
|
370
|
+
end
|
371
|
+
|
372
|
+
user = User.new
|
373
|
+
user.interests << :music
|
374
|
+
user.interests << :sports
|
375
|
+
```
|
376
|
+
|
377
|
+
and with ActiveRecord:
|
378
|
+
|
379
|
+
```ruby
|
380
|
+
class User < ActiveRecord::Base
|
381
|
+
extend Enumerize
|
382
|
+
|
383
|
+
serialize :interests, Array
|
384
|
+
enumerize :interests, in: [:music, :sports], multiple: true
|
385
|
+
end
|
386
|
+
```
|
387
|
+
|
388
|
+
get an array of all text values:
|
389
|
+
|
390
|
+
```ruby
|
391
|
+
@user.interests.texts # shortcut for @user.interests.map(&:text)
|
392
|
+
```
|
393
|
+
|
394
|
+
Also, the reader method can be overridden, referencing the enumerized attribute value using `super`:
|
395
|
+
|
396
|
+
```ruby
|
397
|
+
def status
|
398
|
+
if current_user.admin?
|
399
|
+
"Super #{super}"
|
400
|
+
else
|
401
|
+
super
|
402
|
+
end
|
403
|
+
end
|
404
|
+
```
|
405
|
+
|
406
|
+
---
|
407
|
+
|
408
|
+
## Forms
|
409
|
+
|
410
|
+
### SimpleForm
|
411
|
+
|
412
|
+
If you are using SimpleForm gem you don't need to specify input type (`:select` by default) and collection:
|
413
|
+
|
414
|
+
```erb
|
415
|
+
<%= simple_form_for @user do |f| %>
|
416
|
+
<%= f.input :status %>
|
417
|
+
<% end %>
|
418
|
+
```
|
419
|
+
|
420
|
+
and if you want it as radio buttons:
|
421
|
+
|
422
|
+
```erb
|
423
|
+
<%= simple_form_for @user do |f| %>
|
424
|
+
<%= f.input :status, :as => :radio_buttons %>
|
425
|
+
<% end %>
|
426
|
+
```
|
427
|
+
|
428
|
+
Please note that Enumerize overwrites the I18n keys of SimpleForm collections. The enumerized keys are used instead of the SimpleForm ones for inputs concerning enumerized attributes. If you don't want this just pass `:collection` option to the `input` call.
|
429
|
+
|
430
|
+
### Formtastic
|
431
|
+
|
432
|
+
If you are using Formtastic gem you also don't need to specify input type (`:select` by default) and collection:
|
433
|
+
|
434
|
+
```erb
|
435
|
+
<%= semantic_form_for @user do |f| %>
|
436
|
+
<%= f.input :status %>
|
437
|
+
<% end %>
|
438
|
+
```
|
439
|
+
|
440
|
+
and if you want it as radio buttons:
|
441
|
+
|
442
|
+
```erb
|
443
|
+
<%= semantic_form_for @user do |f| %>
|
444
|
+
<%= f.input :status, :as => :radio %>
|
445
|
+
<% end %>
|
446
|
+
```
|
447
|
+
|
448
|
+
---
|
449
|
+
|
450
|
+
## Testing
|
451
|
+
|
452
|
+
### RSpec
|
453
|
+
|
454
|
+
Also you can use builtin RSpec matcher:
|
455
|
+
|
456
|
+
```ruby
|
457
|
+
class User
|
458
|
+
extend Enumerize
|
459
|
+
|
460
|
+
enumerize :status, in: [:student, :employed, :retired]
|
461
|
+
end
|
462
|
+
|
463
|
+
describe User do
|
464
|
+
it { should enumerize(:status) }
|
465
|
+
|
466
|
+
# or with RSpec 3 expect syntax
|
467
|
+
it { is_expected.to enumerize(:status) }
|
468
|
+
end
|
469
|
+
```
|
470
|
+
|
471
|
+
#### Qualifiers
|
472
|
+
|
473
|
+
##### in
|
474
|
+
|
475
|
+
Use `in` to test usage of the `:in` option.
|
476
|
+
|
477
|
+
```ruby
|
478
|
+
class User
|
479
|
+
extend Enumerize
|
480
|
+
|
481
|
+
enumerize :status, in: [:student, :employed, :retired]
|
482
|
+
end
|
483
|
+
|
484
|
+
describe User do
|
485
|
+
it { should enumerize(:status).in(:student, :employed, :retired) }
|
486
|
+
end
|
487
|
+
```
|
488
|
+
|
489
|
+
You can test enumerized attribute value using custom values with the `in`
|
490
|
+
qualifier.
|
491
|
+
|
492
|
+
```ruby
|
493
|
+
class User
|
494
|
+
extend Enumerize
|
495
|
+
|
496
|
+
enumerize :role, in: { user: 0, admin: 1 }
|
497
|
+
end
|
498
|
+
|
499
|
+
describe User do
|
500
|
+
it { should enumerize(:role).in(user: 0, admin: 1) }
|
501
|
+
end
|
502
|
+
```
|
503
|
+
|
504
|
+
##### with_default
|
505
|
+
|
506
|
+
Use `with_default` to test usage of the `:default` option.
|
507
|
+
|
508
|
+
```ruby
|
509
|
+
class User
|
510
|
+
extend Enumerize
|
511
|
+
|
512
|
+
enumerize :role, in: [:user, :admin], default: :user
|
513
|
+
end
|
514
|
+
|
515
|
+
describe User do
|
516
|
+
it { should enumerize(:user).in(:user, :admin).with_default(:user) }
|
517
|
+
end
|
518
|
+
```
|
519
|
+
|
520
|
+
##### with_i18n_scope
|
521
|
+
|
522
|
+
Use `with_i18n_scope` to test usage of the `:i18n_scope` option.
|
523
|
+
|
524
|
+
```ruby
|
525
|
+
class User
|
526
|
+
extend Enumerize
|
527
|
+
|
528
|
+
enumerize :status, in: [:student, :employed, :retired], i18n_scope: 'status'
|
529
|
+
end
|
530
|
+
|
531
|
+
describe User do
|
532
|
+
it { should enumerize(:status).in(:student, :employed, :retired).with_i18n_scope('status') }
|
533
|
+
end
|
534
|
+
```
|
535
|
+
|
536
|
+
##### with_predicates
|
537
|
+
|
538
|
+
Use `with_predicates` to test usage of the `:predicates` option.
|
539
|
+
|
540
|
+
```ruby
|
541
|
+
class User
|
542
|
+
extend Enumerize
|
543
|
+
|
544
|
+
enumerize :status, in: [:student, :employed, :retired], predicates: true
|
545
|
+
end
|
546
|
+
|
547
|
+
describe User do
|
548
|
+
it { should enumerize(:status).in(:student, :employed, :retired).with_predicates(true) }
|
549
|
+
end
|
550
|
+
```
|
551
|
+
|
552
|
+
You can text prefixed predicates with the `with_predicates` qualifiers.
|
553
|
+
|
554
|
+
```ruby
|
555
|
+
class User
|
556
|
+
extend Enumerize
|
557
|
+
|
558
|
+
enumerize :status, in: [:student, :employed, :retired], predicates: { prefix: true }
|
559
|
+
end
|
560
|
+
|
561
|
+
describe User do
|
562
|
+
it { should enumerize(:status).in(:student, :employed, :retired).with_predicates(prefix: true) }
|
563
|
+
end
|
564
|
+
```
|
565
|
+
|
566
|
+
##### with_scope
|
567
|
+
|
568
|
+
Use `with_scope` to test usage of the `:scope` option.
|
569
|
+
|
570
|
+
```ruby
|
571
|
+
class User
|
572
|
+
extend Enumerize
|
573
|
+
|
574
|
+
enumerize :status, in: [:student, :employed, :retired], scope: true
|
575
|
+
end
|
576
|
+
|
577
|
+
describe User do
|
578
|
+
it { should enumerize(:status).in(:student, :employed, :retired).with_scope(true) }
|
579
|
+
end
|
580
|
+
```
|
581
|
+
|
582
|
+
You can test a custom scope with the `with_scope` qualifiers.
|
583
|
+
|
584
|
+
```ruby
|
585
|
+
class User
|
586
|
+
extend Enumerize
|
587
|
+
|
588
|
+
enumerize :status, in: [:student, :employed], scope: :employable
|
589
|
+
end
|
590
|
+
|
591
|
+
describe User do
|
592
|
+
it { should enumerize(:status).in(:student, :employed, :retired).with_scope(scope: :employable) }
|
593
|
+
end
|
594
|
+
```
|
595
|
+
|
596
|
+
##### with_multiple
|
597
|
+
|
598
|
+
Use `with_multiple` to test usage of the `:multiple` option.
|
599
|
+
|
600
|
+
```ruby
|
601
|
+
class User
|
602
|
+
extend Enumerize
|
603
|
+
|
604
|
+
enumerize :status, in: [:student, :employed, :retired], multiple: true
|
605
|
+
end
|
606
|
+
|
607
|
+
describe User do
|
608
|
+
it { should enumerize(:status).in(:student, :employed, :retired).with_multiple(true) }
|
609
|
+
end
|
610
|
+
```
|
611
|
+
|
612
|
+
### Minitest with Shoulda
|
613
|
+
|
614
|
+
You can use the RSpec matcher with shoulda in your tests by adding two lines in your `test_helper.rb` inside `class ActiveSupport::TestCase` definition:
|
615
|
+
|
616
|
+
```ruby
|
617
|
+
class ActiveSupport::TestCase
|
618
|
+
ActiveRecord::Migration.check_pending!
|
619
|
+
|
620
|
+
require 'enumerize/integrations/rspec'
|
621
|
+
extend Enumerize::Integrations::RSpec
|
622
|
+
|
623
|
+
...
|
624
|
+
end
|
625
|
+
```
|
626
|
+
|
627
|
+
### Other Integrations
|
628
|
+
|
629
|
+
Enumerize integrates with the following automatically:
|
630
|
+
|
631
|
+
- [RailsAdmin](https://github.com/sferik/rails_admin/)
|
632
|
+
|
633
|
+
---
|
634
|
+
|
635
|
+
## Contributing
|
636
|
+
|
637
|
+
1. Fork it
|
638
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
639
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
640
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
641
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/usr/bin/env rake
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require "bundler/gem_tasks"
|
5
|
+
|
6
|
+
require 'rake/testtask'
|
7
|
+
require 'rspec/core/rake_task'
|
8
|
+
|
9
|
+
Rake::TestTask.new do |t|
|
10
|
+
t.libs << 'test'
|
11
|
+
t.pattern = 'test/*_test.rb'
|
12
|
+
t.verbose = true
|
13
|
+
end
|
14
|
+
|
15
|
+
RSpec::Core::RakeTask.new
|
16
|
+
|
17
|
+
task :default => [:test, :spec]
|
data/enumerize.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/enumerize/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Sergey Nartimov"]
|
6
|
+
gem.email = "team@brainspec.com"
|
7
|
+
gem.licenses = ['MIT']
|
8
|
+
gem.description = %q{Enumerated attributes with I18n and ActiveRecord/Mongoid/MongoMapper support}
|
9
|
+
gem.summary = %q{Enumerated attributes with I18n and ActiveRecord/Mongoid/MongoMapper support}
|
10
|
+
gem.homepage = "https://github.com/brainspec/enumerize"
|
11
|
+
|
12
|
+
gem.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
13
|
+
gem.files = `git ls-files`.split("\n")
|
14
|
+
gem.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
15
|
+
gem.name = "careacademy-enumerize"
|
16
|
+
gem.require_paths = ["lib"]
|
17
|
+
gem.version = Enumerize::VERSION
|
18
|
+
|
19
|
+
gem.required_ruby_version = '>= 2.7'
|
20
|
+
|
21
|
+
gem.add_dependency('activesupport', '>= 3.2')
|
22
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Enumerize
|
4
|
+
module ActiveModelAttributesSupport
|
5
|
+
def enumerize(name, options={})
|
6
|
+
super
|
7
|
+
|
8
|
+
_enumerize_module.dependent_eval do
|
9
|
+
if self.included_modules.include? ::ActiveModel::Attributes
|
10
|
+
include InstanceMethods
|
11
|
+
|
12
|
+
attribute name, Enumerize::ActiveModelAttributesSupport::Type.new(enumerized_attributes[name])
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module InstanceMethods
|
18
|
+
# https://github.com/brainspec/enumerize/issues/74
|
19
|
+
def write_attribute(attr_name, value, *options)
|
20
|
+
if self.class.enumerized_attributes[attr_name]
|
21
|
+
_enumerized_values_for_validation[attr_name.to_s] = value
|
22
|
+
end
|
23
|
+
|
24
|
+
super
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class Type < ActiveModel::Type::Value
|
29
|
+
def type
|
30
|
+
:enumerize
|
31
|
+
end
|
32
|
+
|
33
|
+
def initialize(attr)
|
34
|
+
@attr = attr
|
35
|
+
end
|
36
|
+
|
37
|
+
def serialize(value)
|
38
|
+
v = @attr.find_value(value)
|
39
|
+
v && v.value
|
40
|
+
end
|
41
|
+
|
42
|
+
def deserialize(value)
|
43
|
+
@attr.find_value(value)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|