enumerize 0.8.0 → 2.1.1

Sign up to get free protection for your applications and to get access to all the features.
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