enumerize 2.2.1 → 2.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +73 -0
  3. data/CHANGELOG.md +35 -1
  4. data/Gemfile +2 -3
  5. data/Gemfile.global +2 -10
  6. data/Gemfile.mongo_mapper +2 -3
  7. data/Gemfile.rails60 +6 -0
  8. data/Gemfile.rails61 +6 -0
  9. data/Gemfile.rails70 +9 -0
  10. data/Gemfile.railsmaster +5 -0
  11. data/README.md +205 -94
  12. data/Rakefile +2 -0
  13. data/lib/enumerize/activemodel.rb +2 -0
  14. data/lib/enumerize/activerecord.rb +36 -2
  15. data/lib/enumerize/attribute.rb +19 -11
  16. data/lib/enumerize/attribute_map.rb +2 -0
  17. data/lib/enumerize/base.rb +6 -6
  18. data/lib/enumerize/hooks/formtastic.rb +4 -1
  19. data/lib/enumerize/hooks/sequel_dataset.rb +2 -0
  20. data/lib/enumerize/hooks/simple_form.rb +4 -1
  21. data/lib/enumerize/hooks/uniqueness.rb +2 -0
  22. data/lib/enumerize/integrations/rails_admin.rb +2 -0
  23. data/lib/enumerize/integrations/rspec/matcher.rb +7 -2
  24. data/lib/enumerize/integrations/rspec.rb +2 -0
  25. data/lib/enumerize/module.rb +2 -0
  26. data/lib/enumerize/module_attributes.rb +2 -0
  27. data/lib/enumerize/mongoid.rb +16 -0
  28. data/lib/enumerize/predicatable.rb +3 -1
  29. data/lib/enumerize/predicates.rb +2 -0
  30. data/lib/enumerize/scope/activerecord.rb +16 -0
  31. data/lib/enumerize/scope/mongoid.rb +15 -0
  32. data/lib/enumerize/scope/sequel.rb +16 -0
  33. data/lib/enumerize/sequel.rb +9 -4
  34. data/lib/enumerize/set.rb +2 -0
  35. data/lib/enumerize/utils.rb +12 -0
  36. data/lib/enumerize/value.rb +14 -15
  37. data/lib/enumerize/version.rb +1 -1
  38. data/lib/enumerize.rb +4 -0
  39. data/lib/sequel/plugins/enumerize.rb +2 -0
  40. data/spec/enumerize/integrations/rspec/matcher_spec.rb +13 -10
  41. data/spec/spec_helper.rb +2 -0
  42. data/test/activemodel_test.rb +24 -22
  43. data/test/activerecord_test.rb +229 -92
  44. data/test/attribute_map_test.rb +9 -7
  45. data/test/attribute_test.rb +37 -30
  46. data/test/base_test.rb +38 -36
  47. data/test/formtastic_test.rb +17 -0
  48. data/test/module_attributes_test.rb +10 -8
  49. data/test/mongo_mapper_test.rb +19 -10
  50. data/test/mongoid_test.rb +51 -22
  51. data/test/multiple_test.rb +15 -7
  52. data/test/predicates_test.rb +20 -18
  53. data/test/rails_admin_test.rb +4 -2
  54. data/test/sequel_test.rb +100 -47
  55. data/test/set_test.rb +25 -23
  56. data/test/simple_form_test.rb +17 -0
  57. data/test/support/mock_controller.rb +2 -0
  58. data/test/support/shared_enums.rb +43 -0
  59. data/test/support/view_test_helper.rb +14 -1
  60. data/test/test_helper.rb +2 -0
  61. data/test/value_test.rb +51 -30
  62. metadata +11 -30
  63. data/.travis.yml +0 -35
  64. data/Gemfile.rails42 +0 -7
  65. data/Gemfile.rails50 +0 -7
  66. data/Gemfile.rails52 +0 -7
data/README.md CHANGED
@@ -1,7 +1,35 @@
1
- # Enumerize [![TravisCI](https://secure.travis-ci.org/brainspec/enumerize.svg?branch=master)](http://travis-ci.org/brainspec/enumerize) [![Gemnasium](https://gemnasium.com/brainspec/enumerize.svg)](https://gemnasium.com/brainspec/enumerize)
1
+ # Enumerize [![TravisCI](https://secure.travis-ci.org/brainspec/enumerize.svg?branch=master)](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
- - Ruby 2.2+
21
- - Rails 4.2+
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 :sex, in: [:male, :female]
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
- ActiveRecord:
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 :sex
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 :sex, in: [:male, :female], default: lambda { |user| SexIdentifier.sex_for_name(user.name).to_sym }
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
- Mongoid:
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
- I18n:
129
+ ---
130
+
131
+ ## I18n Support
86
132
 
87
133
  ```ruby
88
134
  en:
89
135
  enumerize:
90
136
  user:
91
- sex:
92
- male: "Male"
93
- female: "Female"
137
+ status:
138
+ student: "Student"
139
+ employed: "Employed"
140
+ retired: "Retiree"
94
141
  ```
95
142
 
96
- or if you use `sex` attribute across several models you can use `defaults` scope:
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
- sex:
103
- male: "Male"
104
- female: "Female"
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 :sex, in: %w[male female], i18n_scope: "sex"
116
- enumerize :color, in: %w[black white], i18n_scope: ["various.colors", "colors"]
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
- sex:
122
- male: "Male"
123
- female: "Female"
124
- various:
125
- colors:
126
- black: "Black"
127
- colors:
128
- white: "White"
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
- get attribute value:
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
- @user.sex_text # or @user.sex.text
203
+ User.status.values # or User.enumerized_attributes[:status].values
204
+ # => ['student', 'employed', 'retired']
144
205
  ```
145
206
 
146
- get all values for enumerized attribute:
207
+ #### I18n text values
208
+
209
+ List of possible I18n text values for an enumerized attribute:
147
210
 
148
211
  ```ruby
149
- User.sex.values # or User.enumerized_attributes[:sex].values
212
+ User.status.values.collect(&:text)
213
+ # => ['Student', 'Employed', 'Retiree']
150
214
  ```
151
215
 
152
- use it with forms (it supports `:only` and `:except` options):
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 :sex, User.sex.options %>
222
+ <%= f.select :status, User.status.options %>
157
223
  <% end %>
158
224
  ```
159
225
 
160
- Boolean methods:
226
+ ---
227
+
228
+ ## Boolean Helper Methods
229
+
230
+ ### Basic
161
231
 
162
232
  ```ruby
163
- user.sex = :male
164
- user.sex.male? #=> true
165
- user.sex.female? #=> false
233
+ user.status = :student
234
+ user.status.student? #=> true
235
+ user.status.retired? #=> false
166
236
  ```
167
237
 
168
- Predicate methods:
238
+ ### Predicate Methods
169
239
 
170
240
  ```ruby
171
241
  class User
172
242
  extend Enumerize
173
243
 
174
- enumerize :sex, in: %w(male female), predicates: true
244
+ enumerize :status, in: %w(student employed retired), predicates: true
175
245
  end
176
246
 
177
247
  user = User.new
178
248
 
179
- user.male? # => false
180
- user.female? # => false
249
+ user.student? # => false
250
+ user.employed? # => false
181
251
 
182
- user.sex = 'male'
252
+ user.status = :student
183
253
 
184
- user.male? # => true
185
- user.female? # => false
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
- Using prefix:
260
+ #### Predicate Prefixes
190
261
 
191
262
  ```ruby
192
263
  class User
193
264
  extend Enumerize
194
265
 
195
- enumerize :sex, in: %w(male female), predicates: { prefix: true }
266
+ enumerize :status, in: %w(student employed retired), predicates: { prefix: true }
196
267
  end
197
268
 
198
269
  user = User.new
199
- user.sex = 'female'
200
- user.sex_female? # => true
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 PersonEnumerations
285
+ module RoleEnumerations
208
286
  extend Enumerize
209
287
 
210
- enumerize :sex, in: %w[male female]
288
+ enumerize :roles, in: %w[user admin]
211
289
  end
212
290
 
213
- class Person
214
- include PersonEnumerations
291
+ class Buyer
292
+ include RoleEnumerations
215
293
  end
216
294
 
217
- class User
218
- include PersonEnumerations
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 :sex, :in => [:male, :female], scope: true
246
- enumerize :status, :in => { active: 1, blocked: 2 }, scope: :having_status
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.with_sex(:female)
250
- # SELECT "users".* FROM "users" WHERE "users"."sex" IN ('female')
331
+ User.with_role(:admin)
332
+ # SELECT "users".* FROM "users" WHERE "users"."role" IN ('admin')
251
333
 
252
- User.without_sex(:male)
253
- # SELECT "users".* FROM "users" WHERE "users"."sex" NOT IN ('male')
334
+ User.without_role(:admin)
335
+ # SELECT "users".* FROM "users" WHERE "users"."role" NOT IN ('admin')
254
336
 
255
- User.having_status(:blocked).with_sex(:male, :female)
256
- # SELECT "users".* FROM "users" WHERE "users"."status" IN (2) AND "users"."sex" IN ('male', 'female')
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 sex
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 :sex %>
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 :sex, :as => :radio_buttons %>
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 :sex %>
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 :sex, :as => :radio %>
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 :sex, in: [:male, :female]
460
+ enumerize :status, in: [:student, :employed, :retired]
351
461
  end
352
462
 
353
463
  describe User do
354
- it { should enumerize(:sex) }
464
+ it { should enumerize(:status) }
355
465
 
356
466
  # or with RSpec 3 expect syntax
357
- it { is_expected.to enumerize(:sex) }
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 :sex, in: [:male, :female]
481
+ enumerize :status, in: [:student, :employed, :retired]
372
482
  end
373
483
 
374
484
  describe User do
375
- it { should enumerize(:sex).in(:male, :female) }
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 :sex, in: { male: 0, female: 1 }
496
+ enumerize :role, in: { user: 0, admin: 1 }
387
497
  end
388
498
 
389
499
  describe User do
390
- it { should enumerize(:sex).in(male: 0, female: 1) }
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 :sex, in: [:male, :female], default: :female
512
+ enumerize :role, in: [:user, :admin], default: :user
403
513
  end
404
514
 
405
515
  describe User do
406
- it { should enumerize(:sex).in(:male, :female).with_default(:female) }
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 :sex, in: [:male, :female], i18n_scope: 'sex'
528
+ enumerize :status, in: [:student, :employed, :retired], i18n_scope: 'status'
419
529
  end
420
530
 
421
531
  describe User do
422
- it { should enumerize(:sex).in(:male, :female).with_i18n_scope('sex') }
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 :sex, in: [:male, :female], predicates: true
544
+ enumerize :status, in: [:student, :employed, :retired], predicates: true
435
545
  end
436
546
 
437
547
  describe User do
438
- it { should enumerize(:sex).in(:male, :female).with_predicates(true) }
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 :sex, in: [:male, :female], predicates: { prefix: true }
558
+ enumerize :status, in: [:student, :employed, :retired], predicates: { prefix: true }
449
559
  end
450
560
 
451
561
  describe User do
452
- it { should enumerize(:sex).in(:male, :female).with_predicates(prefix: true) }
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 :sex, in: [:male, :female], scope: true
574
+ enumerize :status, in: [:student, :employed, :retired], scope: true
465
575
  end
466
576
 
467
577
  describe User do
468
- it { should enumerize(:sex).in(:male, :female).with_scope(true) }
578
+ it { should enumerize(:status).in(:student, :employed, :retired).with_scope(true) }
469
579
  end
470
580
  ```
471
581
 
472
- You can text custom scope with the `with_scope` qualifiers.
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 :sex, in: [:male, :female], scope: :having_sex
588
+ enumerize :status, in: [:student, :employed], scope: :employable
479
589
  end
480
590
 
481
591
  describe User do
482
- it { should enumerize(:sex).in(:male, :female).with_scope(scope: :having_sex) }
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 :sex, in: [:male, :female], multiple: true
604
+ enumerize :status, in: [:student, :employed, :retired], multiple: true
495
605
  end
496
606
 
497
607
  describe User do
498
- it { should enumerize(:sex).in(:male, :female).with_multiple(true) }
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
- * [RailsAdmin](https://github.com/sferik/rails_admin/)
631
+ - [RailsAdmin](https://github.com/sferik/rails_admin/)
522
632
 
633
+ ---
523
634
 
524
635
  ## Contributing
525
636
 
data/Rakefile CHANGED
@@ -1,4 +1,6 @@
1
1
  #!/usr/bin/env rake
2
+ # frozen_string_literal: true
3
+
2
4
  require "bundler/gem_tasks"
3
5
 
4
6
  require 'rake/testtask'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Enumerize
2
4
  module ActiveModelAttributesSupport
3
5
  def enumerize(name, options={})
@@ -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
- decorate_attribute_type(name, :enumerize) do |subtype|
23
- Type.new(enumerized_attributes[name], subtype)
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