enumerize 0.8.0 → 1.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +8 -2
  5. data/CHANGELOG.md +91 -0
  6. data/Gemfile +4 -22
  7. data/{Gemfile.rails4 → Gemfile.global} +2 -5
  8. data/Gemfile.mongo_mapper +5 -0
  9. data/Gemfile.rails40 +5 -0
  10. data/README.md +171 -8
  11. data/Rakefile +2 -4
  12. data/lib/enumerize/activerecord.rb +3 -29
  13. data/lib/enumerize/attribute.rb +41 -9
  14. data/lib/enumerize/base.rb +25 -10
  15. data/lib/enumerize/hooks/sequel_dataset.rb +19 -0
  16. data/lib/enumerize/integrations/rspec/matcher.rb +107 -26
  17. data/lib/enumerize/mongoid.rb +13 -0
  18. data/lib/enumerize/predicatable.rb +7 -16
  19. data/lib/enumerize/predicates.rb +3 -1
  20. data/lib/enumerize/scope/activerecord.rb +37 -0
  21. data/lib/enumerize/scope/mongoid.rb +35 -0
  22. data/lib/enumerize/scope/sequel.rb +40 -0
  23. data/lib/enumerize/sequel.rb +57 -0
  24. data/lib/enumerize/set.rb +18 -8
  25. data/lib/enumerize/value.rb +8 -7
  26. data/lib/enumerize/version.rb +1 -1
  27. data/lib/enumerize.rb +23 -1
  28. data/spec/enumerize/integrations/rspec/matcher_spec.rb +258 -0
  29. data/spec/spec_helper.rb +28 -0
  30. data/test/activerecord_test.rb +58 -7
  31. data/test/attribute_test.rb +22 -0
  32. data/test/formtastic_test.rb +3 -12
  33. data/test/mongo_mapper_test.rb +6 -0
  34. data/test/mongoid_test.rb +55 -6
  35. data/test/multiple_test.rb +21 -0
  36. data/test/predicates_test.rb +6 -0
  37. data/test/sequel_test.rb +291 -0
  38. data/test/set_test.rb +14 -0
  39. data/test/simple_form_test.rb +0 -1
  40. data/test/support/view_test_helper.rb +4 -0
  41. data/test/test_helper.rb +23 -2
  42. data/test/value_test.rb +51 -21
  43. metadata +37 -8
  44. data/lib/enumerize/form_helper.rb +0 -23
  45. data/test/rspec_matcher_test.rb +0 -76
  46. 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: 5542a2d4391256f030660b112b5550d304f54364
4
+ data.tar.gz: 8146fa77598d876ae818b44f923382ec7fa87745
5
5
  SHA512:
6
- metadata.gz: a0226ef792ee39084f80286b886880003659bec15c62e1e98938048e6b3accb03b04330591e92d42a2d79f94fb874d80fe14395b4007d3576ac1285bb0b3ff77
7
- data.tar.gz: 48448538be205b068c3c7f01ca68c6780e7e4d2fd0db6f353455ab1462f8db587e744633cd605c7872b77f6bf6ecd353e1ba076998ebc04108e04322ab024c48
6
+ metadata.gz: 1ee6f8b28d3da326a8ab68a9d5a8639b5dca559b58f32d2104364c540911e26a294d7c733a954075be09aa72a5b4890df8304415e69228c89ece1f52b8411cba
7
+ data.tar.gz: b997d62b2e1e759b50cd89921af5f16a7e88e0356a3eb674540ff5562fdde09259920ca9522f001b38ad33419c251cfbe019305752c6ae2ab9947f4a1caf018b
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
@@ -5,12 +5,18 @@ before_install:
5
5
  - gem install bundler
6
6
  gemfile:
7
7
  - Gemfile
8
- - Gemfile.rails4
9
8
  rvm:
10
9
  - 1.9.3
11
10
  - 2.0.0
12
- - 2.1.0
11
+ - 2.1
12
+ - 2.2
13
13
  - jruby-19mode
14
+ matrix:
15
+ include:
16
+ - rvm: 2.2
17
+ gemfile: Gemfile.rails40
18
+ - rvm: 2.2
19
+ gemfile: Gemfile.mongo_mapper
14
20
  notifications:
15
21
  email:
16
22
  recipients:
data/CHANGELOG.md CHANGED
@@ -1,3 +1,94 @@
1
+ ## master
2
+
3
+ ### enhancements
4
+
5
+ ### bug fix
6
+
7
+ ## 1.1.1 (January 25, 2016)
8
+
9
+ ### bug fix
10
+
11
+ * Fix exception when using predicate methods and enumerized values have dash in it. (by [@nashby](https://github.com/nashby))
12
+
13
+ ## 1.1.0 (November 15, 2015)
14
+
15
+ ### enhancements
16
+ * Add Sequel support. (by [@mrbrdo](https://github.com/mrbrdo))
17
+ * Add qualifiers to RSpec matcher. (by [@maurogeorge](https://github.com/maurogeorge))
18
+ * Support hash in the RSpec matcher. (by [@maurogeorge](https://github.com/maurogeorge))
19
+
20
+ ### bug fix
21
+
22
+ ## 1.0.0 (August 2, 2015)
23
+
24
+ ### enhancements
25
+ * Add `texts` method for getting an array of text values of the enumerized field with multiple type. (by [@huynhquancam](https://github.com/huynhquancam))
26
+ * Drop Rails 3.2 support. (by [@nashby](https://github.com/nashby))
27
+
28
+ ### bug fix
29
+
30
+ * Fix conflicts when Active Record and Mongoid are used at the same time. (by [@matsu911](https://github.com/matsu911))
31
+
32
+ ## 0.11.0 (March 29, 2015) ##
33
+
34
+ ### enhancements
35
+ * Add ability to set default value for enumerized field with multiple type. (by [@nashby](https://github.com/nashby))
36
+ * Support Rails 4.2. (by [@lest](https://github.com/lest))
37
+
38
+ ### bug fix
39
+ * Use Mongoid's `:in` method for generated scopes, fix chained scopes. (by [@nashby](https://github.com/nashby))
40
+ * Use `after_initialize` callback to set default value in Mongoid documents. (by [@nashby](https://github.com/nashby))
41
+
42
+ ## 0.10.1 (March 4, 2015) ##
43
+
44
+ ### bug fix
45
+
46
+ * Use method_missing instead of defining singleton class methods to allow Marshal serialization (by [@lest](https://github.com/lest))
47
+
48
+ ## 0.10.0 (February 17, 2015) ##
49
+
50
+ ### enhancements
51
+
52
+ * Add scopes support to mongoid documents (by [@nashby](https://github.com/nashby))
53
+ * Use underscore.humanize in #text to make use of Inflector acronyms (by [@mintuhouse](https://github.com/mintuhouse))
54
+ * Raise an exception when :scope option is used together with :multiple option (by [@maurogeorge](https://github.com/maurogeorge))
55
+ * Use alias_method_chain instead of overriding Class#inherited (by [@yuroyoro](https://github.com/yuroyoro))
56
+ * Shortcut methods to retrieve enumerize values (by [@CyborgMaster](https://github.com/CyborgMaster))
57
+ * Extend equality operator to support comparing with symbols and custom values (e.g. integers) (by [@CyborgMaster](https://github.com/CyborgMaster))
58
+
59
+ ## 0.9.0 (December 11, 2014) ##
60
+
61
+ ### enhancements
62
+
63
+ * Add :value_class option (by [@lest](https://github.com/lest))
64
+ * 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:
65
+
66
+ ```yml
67
+ en:
68
+ enumerize:
69
+ defaults:
70
+ sex:
71
+ male: Male
72
+ female: Female
73
+ ```
74
+
75
+ You still can use the old solution without "default" scope:
76
+
77
+ ```yml
78
+ en:
79
+ enumerize:
80
+ sex:
81
+ male: Male
82
+ female: Female
83
+ ```
84
+ (by [@nashby](https://github.com/nashby))
85
+
86
+ ### bug fix
87
+ * Store values for validation using string keys (by [@nagyt234](https://github.com/nagyt234))
88
+ * Store custom values for multiple attributes (by [@lest](https://github.com/lest))
89
+ * Support validations after using AR#becomes (by [@lest](https://github.com/lest))
90
+ * Do not try to set attribute for not selected attributes (by [@dany1468](https://github.com/dany1468))
91
+
1
92
  ## 0.8.0 (March 4, 2014) ##
2
93
 
3
94
  ### enhancements
data/Gemfile CHANGED
@@ -1,23 +1,5 @@
1
- source 'https://rubygems.org'
1
+ eval_gemfile('Gemfile.global')
2
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
19
-
20
- gem 'mongoid'
21
- gem 'mongo_mapper'
22
- gem 'simple_form'
23
- gem 'formtastic'
3
+ gem 'minitest', '~> 5.8'
4
+ gem 'rails', '4.2.4', :require => false
5
+ gem 'mongoid', '~> 5.0'
@@ -3,12 +3,11 @@ source 'https://rubygems.org'
3
3
  gemspec
4
4
 
5
5
  gem 'rake'
6
- gem 'minitest', '~> 4.1'
7
6
  gem 'rspec', :require => false
8
7
 
9
- gem 'rails', '4.0.1', :require => false
10
8
  gem 'sqlite3', :platform => [:ruby, :mswin, :mingw]
11
9
  gem 'activerecord-jdbcsqlite3-adapter', :platform => :jruby
10
+ gem 'sequel'
12
11
 
13
12
  platforms :rbx do
14
13
  gem 'rubysl', '~> 2.0'
@@ -17,7 +16,5 @@ platforms :rbx do
17
16
  gem 'rubysl-test-unit'
18
17
  end
19
18
 
20
- gem 'mongoid', github: 'mongoid/mongoid', ref: 'f91feef0a0c6b83a1b878e154f1014536aa1c298'
21
- gem 'mongo_mapper', github: 'jnunemaker/mongomapper'
22
19
  gem 'simple_form'
23
- gem 'formtastic', github: 'justinfrench/formtastic'
20
+ gem 'formtastic'
@@ -0,0 +1,5 @@
1
+ eval_gemfile('Gemfile.global')
2
+
3
+ gem 'minitest', '~> 5.8'
4
+ gem 'rails', '4.2.4', :require => false
5
+ gem 'mongo_mapper'
data/Gemfile.rails40 ADDED
@@ -0,0 +1,5 @@
1
+ eval_gemfile('Gemfile.global')
2
+
3
+ gem 'minitest', '~> 4.1'
4
+ gem 'rails', '4.0.13', :require => false
5
+ gem 'mongoid'
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
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)
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
@@ -239,6 +251,8 @@ User.having_status(:blocked).with_sex(:male, :female)
239
251
  # SELECT "users".* FROM "users" WHERE "users"."status" IN (2) AND "users"."sex" IN ('male', 'female')
240
252
  ```
241
253
 
254
+ :warning: It is not possible to define a scope when using the `:multiple` option. :warning:
255
+
242
256
  Array-like attributes with plain ruby objects:
243
257
 
244
258
  ```ruby
@@ -264,6 +278,12 @@ class User < ActiveRecord::Base
264
278
  end
265
279
  ```
266
280
 
281
+ get an array of all text values:
282
+
283
+ ```ruby
284
+ @user.interests.texts # shortcut for @user.interests.map(&:text)
285
+ ```
286
+
267
287
  ### SimpleForm
268
288
 
269
289
  If you are using SimpleForm gem you don't need to specify input type (`:select` by default) and collection:
@@ -308,12 +328,155 @@ Also you can use builtin RSpec matcher:
308
328
  class User
309
329
  extend Enumerize
310
330
 
311
- enumerize :sex, in: [:male, :female], default: :male
331
+ enumerize :sex, in: [:male, :female]
332
+ end
333
+
334
+ describe User do
335
+ it { should enumerize(:sex) }
336
+
337
+ # or with RSpec 3 expect syntax
338
+ it { is_expected.to enumerize(:sex) }
339
+ end
340
+ ```
341
+
342
+ #### Qualifiers
343
+
344
+ ##### in
345
+
346
+ Use `in` to test usage of the `:in` option.
347
+
348
+ ```ruby
349
+ class User
350
+ extend Enumerize
351
+
352
+ enumerize :sex, in: [:male, :female]
312
353
  end
313
354
 
314
355
  describe User do
315
356
  it { should enumerize(:sex).in(:male, :female) }
316
- it { should enumerize(:sex).in(:male, :female).with_default(:male) }
357
+ end
358
+ ```
359
+
360
+ You can test enumerized attribute value using custom values with the `in`
361
+ qualifier.
362
+
363
+ ```ruby
364
+ class User
365
+ extend Enumerize
366
+
367
+ enumerize :sex, in: { male: 0, female: 1 }
368
+ end
369
+
370
+ describe User do
371
+ it { should enumerize(:sex).in(male: 0, female: 1) }
372
+ end
373
+ ```
374
+
375
+ ##### with_default
376
+
377
+ Use `with_default` to test usage of the `:default` option.
378
+
379
+ ```ruby
380
+ class User
381
+ extend Enumerize
382
+
383
+ enumerize :sex, in: [:male, :female], default: :female
384
+ end
385
+
386
+ describe User do
387
+ it { should enumerize(:sex).in(:male, :female).with_default(:female) }
388
+ end
389
+ ```
390
+
391
+ ##### with_i18n_scope
392
+
393
+ Use `with_i18n_scope` to test usage of the `:i18n_scope` option.
394
+
395
+ ```ruby
396
+ class User
397
+ extend Enumerize
398
+
399
+ enumerize :sex, in: [:male, :female], i18n_scope: 'sex'
400
+ end
401
+
402
+ describe User do
403
+ it { should enumerize(:sex).in(:male, :female).with_i18n_scope('sex') }
404
+ end
405
+ ```
406
+
407
+ ##### with_predicates
408
+
409
+ Use `with_predicates` to test usage of the `:predicates` option.
410
+
411
+ ```ruby
412
+ class User
413
+ extend Enumerize
414
+
415
+ enumerize :sex, in: [:male, :female], predicates: true
416
+ end
417
+
418
+ describe User do
419
+ it { should enumerize(:sex).in(:male, :female).with_predicates(true) }
420
+ end
421
+ ```
422
+
423
+ You can text prefixed predicates with the `with_predicates` qualifiers.
424
+
425
+ ```ruby
426
+ class User
427
+ extend Enumerize
428
+
429
+ enumerize :sex, in: [:male, :female], predicates: { prefix: true }
430
+ end
431
+
432
+ describe User do
433
+ it { should enumerize(:sex).in(:male, :female).with_predicates(prefix: true) }
434
+ end
435
+ ```
436
+
437
+ ##### with_scope
438
+
439
+ Use `with_scope` to test usage of the `:scope` option.
440
+
441
+ ```ruby
442
+ class User
443
+ extend Enumerize
444
+
445
+ enumerize :sex, in: [:male, :female], scope: true
446
+ end
447
+
448
+ describe User do
449
+ it { should enumerize(:sex).in(:male, :female).with_scope(true) }
450
+ end
451
+ ```
452
+
453
+ You can text custom scope with the `with_scope` qualifiers.
454
+
455
+ ```ruby
456
+ class User
457
+ extend Enumerize
458
+
459
+ enumerize :sex, in: [:male, :female], scope: :having_sex
460
+ end
461
+
462
+ describe User do
463
+ it { should enumerize(:sex).in(:male, :female).with_scope(scope: :having_sex) }
464
+ end
465
+ ```
466
+
467
+ ##### with_multiple
468
+
469
+ Use `with_multiple` to test usage of the `:multiple` option.
470
+
471
+ ```ruby
472
+ class User
473
+ extend Enumerize
474
+
475
+ enumerize :sex, in: [:male, :female], multiple: true
476
+ end
477
+
478
+ describe User do
479
+ it { should enumerize(:sex).in(:male, :female).with_multiple(true) }
317
480
  end
318
481
  ```
319
482
 
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]
@@ -4,11 +4,7 @@ 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
 
14
10
  # Since Rails use `allocate` method on models and initializes them with `init_with` method.
@@ -21,31 +17,11 @@ module Enumerize
21
17
  end
22
18
  end
23
19
 
24
- private
25
-
26
- def _define_scope_methods!(name, options)
27
- scope_name = options[:scope] == true ? "with_#{name}" : options[:scope]
28
-
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))
40
- end
41
- end
42
- end
43
-
44
20
  module InstanceMethods
45
21
  # https://github.com/brainspec/enumerize/issues/74
46
22
  def write_attribute(attr_name, value)
47
23
  if self.class.enumerized_attributes[attr_name]
48
- _enumerized_values_for_validation[attr_name] = value
24
+ _enumerized_values_for_validation[attr_name.to_s] = value
49
25
  end
50
26
 
51
27
  super
@@ -55,9 +31,7 @@ module Enumerize
55
31
  def becomes(klass)
56
32
  became = super
57
33
  klass.enumerized_attributes.each do |attr|
58
- if attr.is_a? Multiple
59
- became.send("#{attr.name}=", send(attr.name))
60
- end
34
+ became.send("#{attr.name}=", send(attr.name))
61
35
  end
62
36
 
63
37
  became
@@ -4,12 +4,16 @@ module Enumerize
4
4
 
5
5
  def initialize(klass, name, options={})
6
6
  raise ArgumentError, ':in option is required' unless options[:in]
7
+ raise ArgumentError, ':scope option does not work with option :multiple' if options[:multiple] && options[:scope]
7
8
 
8
9
  extend Multiple if options[:multiple]
9
10
 
10
11
  @klass = klass
11
12
  @name = name.to_sym
12
- @values = Array(options[:in]).map { |v| Value.new(self, *v) }
13
+
14
+ value_class = options.fetch(:value_class, Value)
15
+ @values = Array(options[:in]).map { |v| value_class.new(self, *v) }
16
+
13
17
  @value_hash = Hash[@values.map { |v| [v.value.to_s, v] }]
14
18
  @value_hash.merge! Hash[@values.map { |v| [v.to_s, v] }]
15
19
 
@@ -36,6 +40,10 @@ module Enumerize
36
40
  @value_hash[value.to_s] unless value.nil?
37
41
  end
38
42
 
43
+ def find_values(*values)
44
+ values.map { |value| find_value(value) }.compact
45
+ end
46
+
39
47
  def i18n_scopes
40
48
  @i18n_scopes ||= if i18n_scope
41
49
  scopes = Array(i18n_scope)
@@ -67,6 +75,10 @@ module Enumerize
67
75
  values.map { |v| [v.text, v.to_s] }
68
76
  end
69
77
 
78
+ def respond_to_missing?(method, include_private=false)
79
+ @value_hash.include?(method.to_s) || super
80
+ end
81
+
70
82
  def define_methods!(mod)
71
83
  mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
72
84
  def #{name}
@@ -84,8 +96,6 @@ module Enumerize
84
96
  end
85
97
 
86
98
  def #{name}=(new_value)
87
- _enumerized_values_for_validation[:#{name}] = new_value.nil? ? nil : new_value.to_s
88
-
89
99
  allowed_value_or_nil = self.class.enumerized_attributes[:#{name}].find_value(new_value)
90
100
  allowed_value_or_nil = allowed_value_or_nil.value unless allowed_value_or_nil.nil?
91
101
 
@@ -96,6 +106,10 @@ module Enumerize
96
106
  else
97
107
  @#{name} = allowed_value_or_nil
98
108
  end
109
+
110
+ _enumerized_values_for_validation['#{name}'] = new_value.nil? ? nil : new_value.to_s
111
+
112
+ allowed_value_or_nil
99
113
  end
100
114
 
101
115
  def #{name}_text
@@ -107,9 +121,27 @@ module Enumerize
107
121
  end
108
122
  RUBY
109
123
  end
124
+
125
+ private
126
+
127
+ def method_missing(method)
128
+ if @value_hash.include?(method.to_s)
129
+ find_value(method)
130
+ else
131
+ super
132
+ end
133
+ end
110
134
  end
111
135
 
112
136
  module Multiple
137
+ def find_default_value(value)
138
+ if value.respond_to?(:call)
139
+ value
140
+ else
141
+ find_values(*value)
142
+ end
143
+ end
144
+
113
145
  def define_methods!(mod)
114
146
  mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
115
147
  def #{name}
@@ -131,19 +163,19 @@ module Enumerize
131
163
  end
132
164
 
133
165
  def #{name}=(values)
134
- _enumerized_values_for_validation[:#{name}] = values.respond_to?(:map) ? values.map(&:to_s) : values
135
-
136
166
  @_#{name}_enumerized_set = Enumerize::Set.new(self, self.class.enumerized_attributes[:#{name}], values)
137
- string_values = #{name}.values.map(&:to_str)
167
+ raw_values = #{name}.values.map(&:value)
138
168
 
139
169
  if defined?(super)
140
- super string_values
170
+ super raw_values
141
171
  elsif respond_to?(:write_attribute, true)
142
- write_attribute '#{name}', string_values
172
+ write_attribute '#{name}', raw_values
143
173
  else
144
- @#{name} = string_values
174
+ @#{name} = raw_values
145
175
  end
146
176
 
177
+ _enumerized_values_for_validation['#{name}'] = values.respond_to?(:map) ? values.map(&:to_s) : values
178
+
147
179
  #{name}
148
180
  end
149
181
  RUBY
@@ -6,6 +6,15 @@ module Enumerize
6
6
  if base.respond_to?(:validate)
7
7
  base.validate :_validate_enumerized_attributes
8
8
  end
9
+
10
+ class << base
11
+ if (method_defined?(:inherited) || private_method_defined?(:inherited)) && !private_method_defined?(:inherited_without_enumerized)
12
+ alias_method :inherited_without_enumerized, :inherited
13
+ private :inherited_without_enumerized
14
+ end
15
+
16
+ alias_method :inherited, :inherited_with_enumerized
17
+ end
9
18
  end
10
19
 
11
20
  module ClassMethods
@@ -28,9 +37,11 @@ module Enumerize
28
37
  @enumerized_attributes ||= AttributeMap.new
29
38
  end
30
39
 
31
- def inherited(subclass)
40
+ def inherited_with_enumerized(subclass)
32
41
  enumerized_attributes.add_dependant subclass.enumerized_attributes
33
- super
42
+ if respond_to?(:inherited_without_enumerized, true)
43
+ inherited_without_enumerized subclass
44
+ end
34
45
  end
35
46
 
36
47
  private
@@ -50,10 +61,14 @@ module Enumerize
50
61
  end
51
62
 
52
63
  def read_attribute_for_validation(key)
64
+ key = key.to_s
65
+
53
66
  if _enumerized_values_for_validation.has_key?(key)
54
67
  _enumerized_values_for_validation[key]
55
- else
68
+ elsif defined?(super)
56
69
  super
70
+ else
71
+ send(key)
57
72
  end
58
73
  end
59
74
 
@@ -78,15 +93,15 @@ module Enumerize
78
93
 
79
94
  def _set_default_value_for_enumerized_attributes
80
95
  self.class.enumerized_attributes.each do |attr|
81
- # remove after dropping support for Rails 3.x
82
- # https://github.com/brainspec/enumerize/issues/101
83
- attr_value = begin
84
- public_send(attr.name)
85
- rescue ActiveModel::MissingAttributeError
86
- nil
96
+ if respond_to?(attr.name)
97
+ attr_value = public_send(attr.name)
98
+ else
99
+ next
87
100
  end
88
101
 
89
- if !attr_value && !_enumerized_values_for_validation.key?(attr.name)
102
+ value_for_validation = _enumerized_values_for_validation[attr.name.to_s]
103
+
104
+ if (!attr_value || attr_value.empty?) && (!value_for_validation || value_for_validation.empty?)
90
105
  value = attr.default_value
91
106
 
92
107
  if value.respond_to?(:call)