enumerize 0.8.0 → 1.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 (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)