enumerize 0.8.0 → 2.1.1

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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +27 -12
  5. data/CHANGELOG.md +135 -0
  6. data/Gemfile +5 -21
  7. data/Gemfile.global +20 -0
  8. data/Gemfile.mongo_mapper +7 -0
  9. data/Gemfile.rails42 +7 -0
  10. data/Gemfile.rails51 +7 -0
  11. data/README.md +185 -9
  12. data/Rakefile +2 -4
  13. data/enumerize.gemspec +1 -0
  14. data/lib/enumerize/activerecord.rb +55 -27
  15. data/lib/enumerize/attribute.rb +41 -9
  16. data/lib/enumerize/base.rb +28 -17
  17. data/lib/enumerize/hooks/formtastic.rb +3 -8
  18. data/lib/enumerize/hooks/sequel_dataset.rb +15 -0
  19. data/lib/enumerize/hooks/simple_form.rb +5 -11
  20. data/lib/enumerize/hooks/uniqueness.rb +3 -8
  21. data/lib/enumerize/integrations/rspec/matcher.rb +107 -26
  22. data/lib/enumerize/mongoid.rb +13 -0
  23. data/lib/enumerize/predicatable.rb +7 -16
  24. data/lib/enumerize/predicates.rb +3 -1
  25. data/lib/enumerize/scope/activerecord.rb +37 -0
  26. data/lib/enumerize/scope/mongoid.rb +35 -0
  27. data/lib/enumerize/scope/sequel.rb +40 -0
  28. data/lib/enumerize/sequel.rb +57 -0
  29. data/lib/enumerize/set.rb +18 -8
  30. data/lib/enumerize/value.rb +10 -9
  31. data/lib/enumerize/version.rb +3 -1
  32. data/lib/enumerize.rb +23 -1
  33. data/spec/enumerize/integrations/rspec/matcher_spec.rb +258 -0
  34. data/spec/spec_helper.rb +28 -0
  35. data/test/activerecord_test.rb +233 -10
  36. data/test/attribute_test.rb +22 -0
  37. data/test/base_test.rb +7 -7
  38. data/test/formtastic_test.rb +3 -12
  39. data/test/mongo_mapper_test.rb +7 -1
  40. data/test/mongoid_test.rb +63 -7
  41. data/test/multiple_test.rb +21 -0
  42. data/test/predicates_test.rb +6 -0
  43. data/test/sequel_test.rb +291 -0
  44. data/test/set_test.rb +14 -0
  45. data/test/simple_form_test.rb +0 -1
  46. data/test/support/mock_controller.rb +4 -0
  47. data/test/support/view_test_helper.rb +4 -0
  48. data/test/test_helper.rb +23 -2
  49. data/test/value_test.rb +51 -21
  50. metadata +40 -9
  51. data/Gemfile.rails4 +0 -23
  52. data/lib/enumerize/form_helper.rb +0 -23
  53. data/test/rspec_matcher_test.rb +0 -76
  54. data/test/rspec_spec.rb +0 -13
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: f08aba602317c54ffaf5f735e09a205a5d1a624c
4
- data.tar.gz: 87f7613830f330b958dbd0a61f7a7ac89c262623
3
+ metadata.gz: fcc222d35f7bc7e96f344ebac473c10324a42bd9
4
+ data.tar.gz: 4509894cf1723e3df5403c8c93108c316b1ffbb1
5
5
  SHA512:
6
- metadata.gz: a0226ef792ee39084f80286b886880003659bec15c62e1e98938048e6b3accb03b04330591e92d42a2d79f94fb874d80fe14395b4007d3576ac1285bb0b3ff77
7
- data.tar.gz: 48448538be205b068c3c7f01ca68c6780e7e4d2fd0db6f353455ab1462f8db587e744633cd605c7872b77f6bf6ecd353e1ba076998ebc04108e04322ab024c48
6
+ metadata.gz: b1237ba9ede67eefc02b235ec0b74ff2bc6774f89479c22e0e5733dba911b487449bf24e49e82a3be2623cfb432198d6cedf59425f26fab11e36c8c11c073769
7
+ data.tar.gz: 98234b48c034f98cdd43e2379b8ad277dbad8d68088b3cabdfffe71767584028be87ead75629db81fc036862743e16bb5554c680f75d3aa22e814fada961c113
data/.gitignore CHANGED
@@ -2,6 +2,7 @@
2
2
  *.rbc
3
3
  .bundle
4
4
  .config
5
+ .ruby-version
5
6
  .yardoc
6
7
  .idea/
7
8
  enumerize.iml
@@ -12,6 +13,7 @@ _yardoc
12
13
  coverage
13
14
  doc/
14
15
  lib/bundler/man
16
+ log/*
15
17
  pkg
16
18
  rdoc
17
19
  spec/reports
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
data/.travis.yml CHANGED
@@ -1,19 +1,34 @@
1
1
  language: ruby
2
+ sudo: false
2
3
  services:
4
+ - postgresql
3
5
  - mongodb
4
- before_install:
5
- - gem install bundler
6
6
  gemfile:
7
7
  - Gemfile
8
- - Gemfile.rails4
8
+ - Gemfile.rails42
9
+ - Gemfile.rails51
10
+ - Gemfile.mongo_mapper
9
11
  rvm:
10
- - 1.9.3
11
- - 2.0.0
12
- - 2.1.0
13
- - jruby-19mode
12
+ - 2.2.7
13
+ - 2.3.3
14
+ - 2.4.1
15
+ - jruby-9.1.8.0
16
+ env:
17
+ global:
18
+ - DB_USER=postgres
19
+ - DB_PASS=
20
+ matrix:
21
+ - DB=sqlite3
22
+ - DB=postgresql
23
+ matrix:
24
+ fast_finish: true
25
+ allow_failures:
26
+ - rvm: jruby-9.1.8.0
27
+ exclude:
28
+ - gemfile: Gemfile.mongo_mapper
29
+ env: DB=postgresql
30
+ branches:
31
+ only:
32
+ - master
14
33
  notifications:
15
- email:
16
- recipients:
17
- - lest@brainspec.com
18
- - nashby@brainspec.com
19
- - dreamfall@brainspec.com
34
+ email: false
data/CHANGELOG.md CHANGED
@@ -1,3 +1,138 @@
1
+ ## master
2
+
3
+ ### enhancements
4
+
5
+ ### bug fix
6
+
7
+ ## 2.1.1 (May 1, 2017)
8
+
9
+ ### enhancements
10
+
11
+ * Run tests with multiple DBs (SQLite and PostgreSQL). (by [tkawa](https://github.com/tkawa))
12
+
13
+ ### bug fix
14
+
15
+ * Support deserialize and Rails 4.2 methods in the custom AR::Type class. (by [@lest](https://github.com/lest))
16
+ * Support dumping custom AR type to JSON. (by [@lest](https://github.com/lest))
17
+
18
+ ## 2.1.0 (March 31, 2017)
19
+
20
+ ### enhancements
21
+
22
+ * Support Active Record types serialization. (by [@lest](https://github.com/lest))
23
+
24
+ ## 2.0.1 (October 18, 2016)
25
+
26
+ ### bug fix
27
+
28
+ * Support enumerized attributes in #update_all on relation objects. (by [@lest](https://github.com/lest))
29
+
30
+ ## 2.0.0 (August 10, 2016)
31
+
32
+ ### enhancements
33
+
34
+ * Drop support for Ruby older than 2.2. Support only Ruby 2.2+. (by [@nashby](https://github.com/nashby))
35
+ * Drop support for Rails 4.0 and 4.1. Support only Rails 4.2 and newer. (by [@lest](https://github.com/lest))
36
+ * Support Rails 5.0. (by [@nashby](https://github.com/nashby) and [@lest](https://github.com/lest))
37
+ * Allow to pass enumerize values to `ActiveRecord#update_all` (by [@DmitryTsepelev](https://github.com/DmitryTsepelev) and [@ianwhite](https://github.com/ianwhite))
38
+
39
+ ```ruby
40
+ User.update_all(status: :blocked)
41
+ ```
42
+
43
+ ### bug fix
44
+
45
+ * Rescue MissingAttributeError on attribute writing. (by [@embs](https://github.com/embs))
46
+ * Fix presence validation for multiple attributes when the list contains a blank string. (by [@smoriwaki](https://github.com/smoriwaki))
47
+ * Replace deprecated alias_method_chain with Module#prepend. (by [@koenpunt](https://github.com/koenpunt) and [@akm](https://github.com/akm))
48
+ * Make it compatible with `globalize` gem. (by [@falm](https://github.com/falm))
49
+ * Prevent method getter from being called when no default_value is being set. (by [@arjan0307](https://github.com/arjan0307))
50
+
51
+ ## 1.1.1 (January 25, 2016)
52
+
53
+ ### bug fix
54
+
55
+ * Fix exception when using predicate methods and enumerized values have dash in it. (by [@nashby](https://github.com/nashby))
56
+
57
+ ## 1.1.0 (November 15, 2015)
58
+
59
+ ### enhancements
60
+ * Add Sequel support. (by [@mrbrdo](https://github.com/mrbrdo))
61
+ * Add qualifiers to RSpec matcher. (by [@maurogeorge](https://github.com/maurogeorge))
62
+ * Support hash in the RSpec matcher. (by [@maurogeorge](https://github.com/maurogeorge))
63
+
64
+ ### bug fix
65
+
66
+ ## 1.0.0 (August 2, 2015)
67
+
68
+ ### enhancements
69
+ * Add `texts` method for getting an array of text values of the enumerized field with multiple type. (by [@huynhquancam](https://github.com/huynhquancam))
70
+ * Drop Rails 3.2 support. (by [@nashby](https://github.com/nashby))
71
+
72
+ ### bug fix
73
+
74
+ * Fix conflicts when Active Record and Mongoid are used at the same time. (by [@matsu911](https://github.com/matsu911))
75
+
76
+ ## 0.11.0 (March 29, 2015) ##
77
+
78
+ ### enhancements
79
+ * Add ability to set default value for enumerized field with multiple type. (by [@nashby](https://github.com/nashby))
80
+ * Support Rails 4.2. (by [@lest](https://github.com/lest))
81
+
82
+ ### bug fix
83
+ * Use Mongoid's `:in` method for generated scopes, fix chained scopes. (by [@nashby](https://github.com/nashby))
84
+ * Use `after_initialize` callback to set default value in Mongoid documents. (by [@nashby](https://github.com/nashby))
85
+
86
+ ## 0.10.1 (March 4, 2015) ##
87
+
88
+ ### bug fix
89
+
90
+ * Use method_missing instead of defining singleton class methods to allow Marshal serialization (by [@lest](https://github.com/lest))
91
+
92
+ ## 0.10.0 (February 17, 2015) ##
93
+
94
+ ### enhancements
95
+
96
+ * Add scopes support to mongoid documents (by [@nashby](https://github.com/nashby))
97
+ * Use underscore.humanize in #text to make use of Inflector acronyms (by [@mintuhouse](https://github.com/mintuhouse))
98
+ * Raise an exception when :scope option is used together with :multiple option (by [@maurogeorge](https://github.com/maurogeorge))
99
+ * Use alias_method_chain instead of overriding Class#inherited (by [@yuroyoro](https://github.com/yuroyoro))
100
+ * Shortcut methods to retrieve enumerize values (by [@CyborgMaster](https://github.com/CyborgMaster))
101
+ * Extend equality operator to support comparing with symbols and custom values (e.g. integers) (by [@CyborgMaster](https://github.com/CyborgMaster))
102
+
103
+ ## 0.9.0 (December 11, 2014) ##
104
+
105
+ ### enhancements
106
+
107
+ * Add :value_class option (by [@lest](https://github.com/lest))
108
+ * Use 'defaults' scope in the localization file for the attributes that used across several models. This will help to avoid conflicting keys with model names and attribute names. Example:
109
+
110
+ ```yml
111
+ en:
112
+ enumerize:
113
+ defaults:
114
+ sex:
115
+ male: Male
116
+ female: Female
117
+ ```
118
+
119
+ You still can use the old solution without "default" scope:
120
+
121
+ ```yml
122
+ en:
123
+ enumerize:
124
+ sex:
125
+ male: Male
126
+ female: Female
127
+ ```
128
+ (by [@nashby](https://github.com/nashby))
129
+
130
+ ### bug fix
131
+ * Store values for validation using string keys (by [@nagyt234](https://github.com/nagyt234))
132
+ * Store custom values for multiple attributes (by [@lest](https://github.com/lest))
133
+ * Support validations after using AR#becomes (by [@lest](https://github.com/lest))
134
+ * Do not try to set attribute for not selected attributes (by [@dany1468](https://github.com/dany1468))
135
+
1
136
  ## 0.8.0 (March 4, 2014) ##
2
137
 
3
138
  ### enhancements
data/Gemfile CHANGED
@@ -1,23 +1,7 @@
1
- source 'https://rubygems.org'
2
-
3
- gemspec
4
-
5
- gem 'rake'
6
- gem 'minitest', '~> 4.1'
7
- gem 'rspec', :require => false
8
-
9
- gem 'rails', '~> 3.2.0', :require => false
10
- gem 'sqlite3', :platform => [:ruby, :mswin, :mingw]
11
- gem 'activerecord-jdbcsqlite3-adapter', :platform => :jruby
12
-
13
- platforms :rbx do
14
- gem 'rubysl', '~> 2.0'
15
- gem 'psych'
16
- gem 'rubinius-developer_tools'
17
- gem 'rubysl-test-unit'
18
- end
1
+ eval_gemfile('Gemfile.global')
19
2
 
3
+ gem 'minitest', '~> 5.8'
4
+ gem 'rails', '5.0.2', require: false
5
+ gem 'activerecord-jdbcsqlite3-adapter', github: 'jruby/activerecord-jdbc-adapter', branch: 'rails-5', platform: :jruby
6
+ gem 'activerecord-jdbcpostgresql-adapter', github: 'jruby/activerecord-jdbc-adapter', branch: 'rails-5', platform: :jruby
20
7
  gem 'mongoid'
21
- gem 'mongo_mapper'
22
- gem 'simple_form'
23
- gem 'formtastic'
data/Gemfile.global ADDED
@@ -0,0 +1,20 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
4
+
5
+ gem 'rake'
6
+ gem 'rspec', :require => false
7
+
8
+ gem 'sqlite3', :platform => [:ruby, :mswin, :mingw]
9
+ gem 'pg', :platform => [:ruby, :mswin, :mingw]
10
+ gem 'sequel'
11
+
12
+ platforms :rbx do
13
+ gem 'rubysl', '~> 2.0'
14
+ gem 'psych'
15
+ gem 'rubinius-developer_tools'
16
+ gem 'rubysl-test-unit'
17
+ end
18
+
19
+ gem 'simple_form'
20
+ gem 'formtastic'
@@ -0,0 +1,7 @@
1
+ eval_gemfile('Gemfile.global')
2
+
3
+ gem 'minitest', '~> 5.8'
4
+ gem 'rails', '4.2.8', :require => false
5
+ gem 'activerecord-jdbcsqlite3-adapter', platform: :jruby
6
+ gem 'activerecord-jdbcpostgresql-adapter', platform: :jruby
7
+ gem 'mongo_mapper'
data/Gemfile.rails42 ADDED
@@ -0,0 +1,7 @@
1
+ eval_gemfile('Gemfile.global')
2
+
3
+ gem 'minitest', '~> 5.8'
4
+ gem 'rails', '4.2.8', :require => false
5
+ gem 'activerecord-jdbcsqlite3-adapter', platform: :jruby
6
+ gem 'activerecord-jdbcpostgresql-adapter', platform: :jruby
7
+ gem 'mongoid', '~> 5.0'
data/Gemfile.rails51 ADDED
@@ -0,0 +1,7 @@
1
+ eval_gemfile('Gemfile.global')
2
+
3
+ gem 'minitest', '~> 5.8'
4
+ gem 'rails', '5.1.0.rc1', require: false
5
+ gem 'activerecord-jdbcsqlite3-adapter', github: 'jruby/activerecord-jdbc-adapter', branch: 'rails-5', platform: :jruby
6
+ gem 'activerecord-jdbcpostgresql-adapter', github: 'jruby/activerecord-jdbc-adapter', branch: 'rails-5', platform: :jruby
7
+ gem 'mongoid', github: 'mongodb/mongoid'
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
- # Enumerize [![TravisCI](https://secure.travis-ci.org/brainspec/enumerize.png?branch=master)](http://travis-ci.org/brainspec/enumerize) [![Gemnasium](https://gemnasium.com/brainspec/enumerize.png)](https://gemnasium.com/brainspec/enumerize)
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)
2
2
 
3
- Enumerated attributes with I18n and ActiveRecord/Mongoid/MongoMapper support
3
+ Enumerated attributes with I18n and ActiveRecord/Mongoid/MongoMapper/Sequel support
4
4
 
5
5
  ## Installation
6
6
 
@@ -34,6 +34,17 @@ Note that enumerized values are just identificators so if you want to use multi-
34
34
  ActiveRecord:
35
35
 
36
36
  ```ruby
37
+ class CreateUsers < ActiveRecord::Migration
38
+ def change
39
+ create_table :users do |t|
40
+ t.string :sex
41
+ t.string :role
42
+
43
+ t.timestamps
44
+ end
45
+ end
46
+ end
47
+
37
48
  class User < ActiveRecord::Base
38
49
  extend Enumerize
39
50
 
@@ -78,17 +89,18 @@ en:
78
89
  female: "Female"
79
90
  ```
80
91
 
81
- or if you use `sex` attribute across several models you can use this:
92
+ or if you use `sex` attribute across several models you can use `defaults` scope:
82
93
 
83
94
  ```ruby
84
95
  en:
85
96
  enumerize:
86
- sex:
87
- male: "Male"
88
- female: "Female"
97
+ defaults:
98
+ sex:
99
+ male: "Male"
100
+ female: "Female"
89
101
  ```
90
102
 
91
- You can also pass `i18n_scope` option to specify scope (or array of scopes) storring the translations. Note that `i18n_scope` option does not accept scope as array:
103
+ You can also pass `i18n_scope` option to specify scope (or array of scopes) storing the translations.
92
104
 
93
105
 
94
106
  ```ruby
@@ -168,6 +180,7 @@ user.sex = 'male'
168
180
  user.male? # => true
169
181
  user.female? # => false
170
182
  ```
183
+ :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:
171
184
 
172
185
  Using prefix:
173
186
 
@@ -239,6 +252,8 @@ User.having_status(:blocked).with_sex(:male, :female)
239
252
  # SELECT "users".* FROM "users" WHERE "users"."status" IN (2) AND "users"."sex" IN ('male', 'female')
240
253
  ```
241
254
 
255
+ :warning: It is not possible to define a scope when using the `:multiple` option. :warning:
256
+
242
257
  Array-like attributes with plain ruby objects:
243
258
 
244
259
  ```ruby
@@ -264,6 +279,24 @@ class User < ActiveRecord::Base
264
279
  end
265
280
  ```
266
281
 
282
+ get an array of all text values:
283
+
284
+ ```ruby
285
+ @user.interests.texts # shortcut for @user.interests.map(&:text)
286
+ ```
287
+
288
+ Also, the reader method can be overridden, referencing the enumerized attribute value using `super`:
289
+
290
+ ```ruby
291
+ def sex
292
+ if current_user.admin?
293
+ "Super#{super}"
294
+ else
295
+ super
296
+ end
297
+ end
298
+ ```
299
+
267
300
  ### SimpleForm
268
301
 
269
302
  If you are using SimpleForm gem you don't need to specify input type (`:select` by default) and collection:
@@ -308,12 +341,155 @@ Also you can use builtin RSpec matcher:
308
341
  class User
309
342
  extend Enumerize
310
343
 
311
- enumerize :sex, in: [:male, :female], default: :male
344
+ enumerize :sex, in: [:male, :female]
345
+ end
346
+
347
+ describe User do
348
+ it { should enumerize(:sex) }
349
+
350
+ # or with RSpec 3 expect syntax
351
+ it { is_expected.to enumerize(:sex) }
352
+ end
353
+ ```
354
+
355
+ #### Qualifiers
356
+
357
+ ##### in
358
+
359
+ Use `in` to test usage of the `:in` option.
360
+
361
+ ```ruby
362
+ class User
363
+ extend Enumerize
364
+
365
+ enumerize :sex, in: [:male, :female]
312
366
  end
313
367
 
314
368
  describe User do
315
369
  it { should enumerize(:sex).in(:male, :female) }
316
- it { should enumerize(:sex).in(:male, :female).with_default(:male) }
370
+ end
371
+ ```
372
+
373
+ You can test enumerized attribute value using custom values with the `in`
374
+ qualifier.
375
+
376
+ ```ruby
377
+ class User
378
+ extend Enumerize
379
+
380
+ enumerize :sex, in: { male: 0, female: 1 }
381
+ end
382
+
383
+ describe User do
384
+ it { should enumerize(:sex).in(male: 0, female: 1) }
385
+ end
386
+ ```
387
+
388
+ ##### with_default
389
+
390
+ Use `with_default` to test usage of the `:default` option.
391
+
392
+ ```ruby
393
+ class User
394
+ extend Enumerize
395
+
396
+ enumerize :sex, in: [:male, :female], default: :female
397
+ end
398
+
399
+ describe User do
400
+ it { should enumerize(:sex).in(:male, :female).with_default(:female) }
401
+ end
402
+ ```
403
+
404
+ ##### with_i18n_scope
405
+
406
+ Use `with_i18n_scope` to test usage of the `:i18n_scope` option.
407
+
408
+ ```ruby
409
+ class User
410
+ extend Enumerize
411
+
412
+ enumerize :sex, in: [:male, :female], i18n_scope: 'sex'
413
+ end
414
+
415
+ describe User do
416
+ it { should enumerize(:sex).in(:male, :female).with_i18n_scope('sex') }
417
+ end
418
+ ```
419
+
420
+ ##### with_predicates
421
+
422
+ Use `with_predicates` to test usage of the `:predicates` option.
423
+
424
+ ```ruby
425
+ class User
426
+ extend Enumerize
427
+
428
+ enumerize :sex, in: [:male, :female], predicates: true
429
+ end
430
+
431
+ describe User do
432
+ it { should enumerize(:sex).in(:male, :female).with_predicates(true) }
433
+ end
434
+ ```
435
+
436
+ You can text prefixed predicates with the `with_predicates` qualifiers.
437
+
438
+ ```ruby
439
+ class User
440
+ extend Enumerize
441
+
442
+ enumerize :sex, in: [:male, :female], predicates: { prefix: true }
443
+ end
444
+
445
+ describe User do
446
+ it { should enumerize(:sex).in(:male, :female).with_predicates(prefix: true) }
447
+ end
448
+ ```
449
+
450
+ ##### with_scope
451
+
452
+ Use `with_scope` to test usage of the `:scope` option.
453
+
454
+ ```ruby
455
+ class User
456
+ extend Enumerize
457
+
458
+ enumerize :sex, in: [:male, :female], scope: true
459
+ end
460
+
461
+ describe User do
462
+ it { should enumerize(:sex).in(:male, :female).with_scope(true) }
463
+ end
464
+ ```
465
+
466
+ You can text custom scope with the `with_scope` qualifiers.
467
+
468
+ ```ruby
469
+ class User
470
+ extend Enumerize
471
+
472
+ enumerize :sex, in: [:male, :female], scope: :having_sex
473
+ end
474
+
475
+ describe User do
476
+ it { should enumerize(:sex).in(:male, :female).with_scope(scope: :having_sex) }
477
+ end
478
+ ```
479
+
480
+ ##### with_multiple
481
+
482
+ Use `with_multiple` to test usage of the `:multiple` option.
483
+
484
+ ```ruby
485
+ class User
486
+ extend Enumerize
487
+
488
+ enumerize :sex, in: [:male, :female], multiple: true
489
+ end
490
+
491
+ describe User do
492
+ it { should enumerize(:sex).in(:male, :female).with_multiple(true) }
317
493
  end
318
494
  ```
319
495
 
data/Rakefile CHANGED
@@ -10,8 +10,6 @@ Rake::TestTask.new do |t|
10
10
  t.verbose = true
11
11
  end
12
12
 
13
- RSpec::Core::RakeTask.new('default') do |t|
14
- t.pattern = FileList['test/rspec_spec.rb']
15
- end
13
+ RSpec::Core::RakeTask.new
16
14
 
17
- task :default => :test
15
+ task :default => [:test, :spec]
data/enumerize.gemspec CHANGED
@@ -4,6 +4,7 @@ require File.expand_path('../lib/enumerize/version', __FILE__)
4
4
  Gem::Specification.new do |gem|
5
5
  gem.authors = ["Sergey Nartimov"]
6
6
  gem.email = "team@brainspec.com"
7
+ gem.licenses = ['MIT']
7
8
  gem.description = %q{Enumerated attributes with I18n and ActiveRecord/Mongoid/MongoMapper support}
8
9
  gem.summary = %q{Enumerated attributes with I18n and ActiveRecord/Mongoid/MongoMapper support}
9
10
  gem.homepage = "https://github.com/brainspec/enumerize"
@@ -4,48 +4,34 @@ module Enumerize
4
4
  super
5
5
 
6
6
  _enumerize_module.dependent_eval do
7
- if defined?(::ActiveRecord::Base) && self < ::ActiveRecord::Base
8
- if options[:scope]
9
- _define_scope_methods!(name, options)
10
- end
11
-
7
+ if self < ::ActiveRecord::Base
12
8
  include InstanceMethods
13
9
 
10
+ const_get(:ActiveRecord_Relation).include(RelationMethods)
11
+ const_get(:ActiveRecord_AssociationRelation).include(RelationMethods)
12
+ const_get(:ActiveRecord_Associations_CollectionProxy).include(RelationMethods)
13
+
14
14
  # Since Rails use `allocate` method on models and initializes them with `init_with` method.
15
15
  # This way `initialize` method is not being called, but `after_initialize` callback always gets triggered.
16
16
  after_initialize :_set_default_value_for_enumerized_attributes
17
17
 
18
18
  # https://github.com/brainspec/enumerize/issues/111
19
19
  require 'enumerize/hooks/uniqueness'
20
- end
21
- end
22
- end
23
-
24
- private
25
-
26
- def _define_scope_methods!(name, options)
27
- scope_name = options[:scope] == true ? "with_#{name}" : options[:scope]
28
20
 
29
- define_singleton_method scope_name do |*values|
30
- values = values.map { |value| enumerized_attributes[name].find_value(value).value }
31
- values = values.first if values.size == 1
32
-
33
- where(name => values)
34
- end
35
-
36
- if options[:scope] == true
37
- define_singleton_method "without_#{name}" do |*values|
38
- values = values.map { |value| enumerized_attributes[name].find_value(value).value }
39
- where(arel_table[name].not_in(values))
21
+ unless options[:multiple]
22
+ decorate_attribute_type(name, :enumerize) do |subtype|
23
+ Type.new(enumerized_attributes[name], subtype)
24
+ end
25
+ end
40
26
  end
41
27
  end
42
28
  end
43
29
 
44
30
  module InstanceMethods
45
31
  # https://github.com/brainspec/enumerize/issues/74
46
- def write_attribute(attr_name, value)
32
+ def write_attribute(attr_name, value, *options)
47
33
  if self.class.enumerized_attributes[attr_name]
48
- _enumerized_values_for_validation[attr_name] = value
34
+ _enumerized_values_for_validation[attr_name.to_s] = value
49
35
  end
50
36
 
51
37
  super
@@ -55,13 +41,55 @@ module Enumerize
55
41
  def becomes(klass)
56
42
  became = super
57
43
  klass.enumerized_attributes.each do |attr|
58
- if attr.is_a? Multiple
44
+ # Rescue when column associated to the enum does not exist.
45
+ begin
59
46
  became.send("#{attr.name}=", send(attr.name))
47
+ rescue ActiveModel::MissingAttributeError
60
48
  end
61
49
  end
62
50
 
63
51
  became
64
52
  end
65
53
  end
54
+
55
+ module RelationMethods
56
+ def update_all(updates)
57
+ if updates.is_a?(Hash)
58
+ enumerized_attributes.each do |attr|
59
+ next if updates[attr.name].blank? || attr.kind_of?(Enumerize::Multiple)
60
+ enumerize_value = attr.find_value(updates[attr.name])
61
+ updates[attr.name] = enumerize_value && enumerize_value.value
62
+ end
63
+ end
64
+
65
+ super(updates)
66
+ end
67
+ end
68
+
69
+ class Type < ActiveRecord::Type::Value
70
+ delegate :type, to: :@subtype
71
+
72
+ def initialize(attr, subtype)
73
+ @attr = attr
74
+ @subtype = subtype
75
+ end
76
+
77
+ def serialize(value)
78
+ v = @attr.find_value(value)
79
+ v && v.value
80
+ end
81
+
82
+ alias type_cast_for_database serialize
83
+
84
+ def deserialize(value)
85
+ @attr.find_value(value)
86
+ end
87
+
88
+ alias type_cast_from_database deserialize
89
+
90
+ def as_json(options = nil)
91
+ {attr: @attr.name, subtype: @subtype}.as_json(options)
92
+ end
93
+ end
66
94
  end
67
95
  end