enumerize 2.0.0 → 2.7.0

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 (65) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/ruby.yml +75 -0
  3. data/CHANGELOG.md +117 -3
  4. data/Gemfile +3 -3
  5. data/Gemfile.global +5 -9
  6. data/Gemfile.mongo_mapper +2 -2
  7. data/Gemfile.rails60 +6 -0
  8. data/Gemfile.rails61 +6 -0
  9. data/Gemfile.rails70 +9 -0
  10. data/Gemfile.railsmaster +5 -0
  11. data/README.md +210 -92
  12. data/Rakefile +9 -3
  13. data/enumerize.gemspec +1 -1
  14. data/lib/enumerize/activemodel.rb +47 -0
  15. data/lib/enumerize/activerecord.rb +92 -6
  16. data/lib/enumerize/attribute.rb +19 -11
  17. data/lib/enumerize/attribute_map.rb +2 -0
  18. data/lib/enumerize/base.rb +22 -18
  19. data/lib/enumerize/hooks/formtastic.rb +4 -1
  20. data/lib/enumerize/hooks/sequel_dataset.rb +2 -0
  21. data/lib/enumerize/hooks/simple_form.rb +4 -1
  22. data/lib/enumerize/hooks/uniqueness.rb +5 -1
  23. data/lib/enumerize/integrations/rails_admin.rb +3 -1
  24. data/lib/enumerize/integrations/rspec/matcher.rb +7 -2
  25. data/lib/enumerize/integrations/rspec.rb +3 -0
  26. data/lib/enumerize/module.rb +2 -0
  27. data/lib/enumerize/module_attributes.rb +2 -0
  28. data/lib/enumerize/mongoid.rb +23 -0
  29. data/lib/enumerize/predicatable.rb +3 -1
  30. data/lib/enumerize/predicates.rb +16 -0
  31. data/lib/enumerize/scope/activerecord.rb +16 -0
  32. data/lib/enumerize/scope/mongoid.rb +15 -0
  33. data/lib/enumerize/scope/sequel.rb +16 -0
  34. data/lib/enumerize/sequel.rb +9 -4
  35. data/lib/enumerize/set.rb +2 -0
  36. data/lib/enumerize/utils.rb +12 -0
  37. data/lib/enumerize/value.rb +14 -15
  38. data/lib/enumerize/version.rb +3 -1
  39. data/lib/enumerize.rb +9 -0
  40. data/lib/sequel/plugins/enumerize.rb +18 -0
  41. data/spec/enumerize/integrations/rspec/matcher_spec.rb +13 -10
  42. data/spec/spec_helper.rb +2 -0
  43. data/test/activemodel_test.rb +114 -0
  44. data/test/activerecord_test.rb +327 -78
  45. data/test/attribute_map_test.rb +9 -7
  46. data/test/attribute_test.rb +37 -34
  47. data/test/base_test.rb +117 -65
  48. data/test/formtastic_test.rb +25 -0
  49. data/test/module_attributes_test.rb +10 -8
  50. data/test/mongo_mapper_test.rb +20 -11
  51. data/test/mongoid_test.rb +52 -23
  52. data/test/multiple_test.rb +27 -19
  53. data/test/predicates_test.rb +51 -29
  54. data/test/rails_admin_test.rb +8 -6
  55. data/test/sequel_test.rb +228 -177
  56. data/test/set_test.rb +29 -27
  57. data/test/simple_form_test.rb +25 -0
  58. data/test/support/mock_controller.rb +6 -0
  59. data/test/support/shared_enums.rb +43 -0
  60. data/test/support/view_test_helper.rb +14 -1
  61. data/test/test_helper.rb +10 -0
  62. data/test/value_test.rb +59 -31
  63. metadata +16 -7
  64. data/.travis.yml +0 -18
  65. data/Gemfile.rails42 +0 -6
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Enumerize
2
4
  module ActiveRecordSupport
3
5
  def enumerize(name, options={})
@@ -7,12 +9,32 @@ module Enumerize
7
9
  if self < ::ActiveRecord::Base
8
10
  include InstanceMethods
9
11
 
12
+ const_get(:ActiveRecord_Relation).include(RelationMethods)
13
+ const_get(:ActiveRecord_AssociationRelation).include(RelationMethods)
14
+ const_get(:ActiveRecord_Associations_CollectionProxy).include(RelationMethods)
15
+
10
16
  # Since Rails use `allocate` method on models and initializes them with `init_with` method.
11
17
  # This way `initialize` method is not being called, but `after_initialize` callback always gets triggered.
12
18
  after_initialize :_set_default_value_for_enumerized_attributes
13
19
 
14
20
  # https://github.com/brainspec/enumerize/issues/111
15
21
  require 'enumerize/hooks/uniqueness'
22
+
23
+ unless options[:multiple]
24
+ if ::ActiveRecord.version >= ::Gem::Version.new("7.0.0.alpha")
25
+ attribute(name) do |subtype|
26
+ Type.new(enumerized_attributes[name], subtype)
27
+ end
28
+ elsif ::ActiveRecord.version >= ::Gem::Version.new("6.1.0.alpha")
29
+ decorate_attribute_type(name.to_s) do |subtype|
30
+ Type.new(enumerized_attributes[name], subtype)
31
+ end
32
+ else
33
+ decorate_attribute_type(name, :enumerize) do |subtype|
34
+ Type.new(enumerized_attributes[name], subtype)
35
+ end
36
+ end
37
+ end
16
38
  end
17
39
  end
18
40
  end
@@ -40,17 +62,81 @@ module Enumerize
40
62
 
41
63
  became
42
64
  end
65
+
66
+ def reload(options = nil)
67
+ reloaded = super
68
+
69
+ reloaded.class.enumerized_attributes.each do |attr|
70
+ begin
71
+ # Checks first if the enumerized attribute is in ActiveRecord::Store
72
+ store_attr, _ = reloaded.class.stored_attributes.detect do |_store_attr, keys|
73
+ keys.include?(attr.name)
74
+ end
75
+
76
+ if store_attr.present?
77
+ reloaded.send("#{attr.name}=", reloaded.send(store_attr).with_indifferent_access[attr.name])
78
+ else
79
+ reloaded.send("#{attr.name}=", reloaded[attr.name])
80
+ end
81
+ rescue ActiveModel::MissingAttributeError
82
+ end
83
+ end
84
+
85
+ reloaded
86
+ end
43
87
  end
44
88
 
45
- def update_all(updates)
46
- if updates.is_a?(Hash)
47
- enumerized_attributes.each do |attr|
48
- next if updates[attr.name].blank? || attr.kind_of?(Enumerize::Multiple)
49
- updates[attr.name] = attr.find_value(updates[attr.name]).value
89
+ module RelationMethods
90
+ def update_all(updates)
91
+ if updates.is_a?(Hash)
92
+ enumerized_attributes.each do |attr|
93
+ next if updates[attr.name].blank? || attr.kind_of?(Enumerize::Multiple)
94
+ enumerize_value = attr.find_value(updates[attr.name])
95
+ updates[attr.name] = enumerize_value && enumerize_value.value
96
+ end
50
97
  end
98
+
99
+ super(updates)
100
+ end
101
+ end
102
+
103
+ class Type < ActiveRecord::Type::Value
104
+ delegate :type, to: :@subtype
105
+
106
+ def initialize(attr, subtype)
107
+ @attr = attr
108
+ @subtype = subtype
51
109
  end
52
110
 
53
- super(updates)
111
+ def serialize(value)
112
+ v = @attr.find_value(value)
113
+ (v && v.value) || value
114
+ end
115
+
116
+ alias type_cast_for_database serialize
117
+
118
+ def cast(value)
119
+ @attr.find_value(value)
120
+ end
121
+
122
+ alias type_cast_from_database cast
123
+
124
+ def as_json(options = nil)
125
+ {attr: @attr.name}.as_json(options)
126
+ end
127
+
128
+ def encode_with(coder)
129
+ coder[:class_name] = @attr.klass.name
130
+ coder[:attr_name] = @attr.name
131
+ coder[:subtype] = @subtype
132
+ end
133
+
134
+ def init_with(coder)
135
+ initialize(
136
+ coder[:class_name].constantize.enumerized_attributes[coder[:attr_name]],
137
+ coder[:subtype]
138
+ )
139
+ end
54
140
  end
55
141
  end
56
142
  end
@@ -1,6 +1,8 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Enumerize
2
4
  class Attribute
3
- attr_reader :name, :values, :default_value, :i18n_scope
5
+ attr_reader :klass, :name, :values, :default_value, :i18n_scope, :skip_validations_value
4
6
 
5
7
  def initialize(klass, name, options={})
6
8
  raise ArgumentError, ':in option is required' unless options[:in]
@@ -10,22 +12,20 @@ module Enumerize
10
12
 
11
13
  @klass = klass
12
14
  @name = name.to_sym
15
+ @i18n_scope = options[:i18n_scope]
13
16
 
14
17
  value_class = options.fetch(:value_class, Value)
15
- @values = Array(options[:in]).map { |v| value_class.new(self, *v) }
18
+ @values = Array(options[:in]).map { |v| value_class.new(self, *v).freeze }
16
19
 
17
20
  @value_hash = Hash[@values.map { |v| [v.value.to_s, v] }]
18
21
  @value_hash.merge! Hash[@values.map { |v| [v.to_s, v] }]
19
22
 
20
- if options[:i18n_scope]
21
- raise ArgumentError, ':i18n_scope option accepts only String or Array of strings' unless Array(options[:i18n_scope]).all? { |s| s.is_a?(String) }
22
- @i18n_scope = options[:i18n_scope]
23
- end
24
-
25
23
  if options[:default]
26
24
  @default_value = find_default_value(options[:default])
27
25
  raise ArgumentError, 'invalid default value' unless @default_value
28
26
  end
27
+
28
+ @skip_validations_value = options.fetch(:skip_validations, false)
29
29
  end
30
30
 
31
31
  def find_default_value(value)
@@ -44,11 +44,19 @@ module Enumerize
44
44
  values.map { |value| find_value(value) }.compact
45
45
  end
46
46
 
47
+ def each_value
48
+ values.each { |value| yield value }
49
+ end
50
+
51
+ def value?(value)
52
+ values.include?(value)
53
+ end
54
+
47
55
  def i18n_scopes
48
56
  @i18n_scopes ||= if i18n_scope
49
- scopes = Array(i18n_scope)
57
+ Array(i18n_scope)
50
58
  elsif @klass.respond_to?(:model_name)
51
- scopes = ["enumerize.#{@klass.model_name.i18n_key}.#{name}"]
59
+ ["enumerize.#{@klass.model_name.i18n_key}.#{name}"]
52
60
  else
53
61
  []
54
62
  end
@@ -164,7 +172,7 @@ module Enumerize
164
172
 
165
173
  def #{name}=(values)
166
174
  @_#{name}_enumerized_set = Enumerize::Set.new(self, self.class.enumerized_attributes[:#{name}], values)
167
- raw_values = #{name}.values.map(&:value)
175
+ raw_values = self.#{name}.values.map(&:value)
168
176
 
169
177
  if defined?(super)
170
178
  super raw_values
@@ -176,7 +184,7 @@ module Enumerize
176
184
 
177
185
  _enumerized_values_for_validation['#{name}'] = values.respond_to?(:map) ? values.reject(&:blank?).map(&:to_s) : values
178
186
 
179
- #{name}
187
+ self.#{name}
180
188
  end
181
189
  RUBY
182
190
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Enumerize
2
4
  class AttributeMap
3
5
  attr_reader :attributes
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Enumerize
2
4
  module Base
3
5
  def self.included(base)
@@ -47,7 +49,7 @@ module Enumerize
47
49
  end
48
50
  end
49
51
 
50
- def initialize(*)
52
+ def initialize(...)
51
53
  super
52
54
  _set_default_value_for_enumerized_attributes
53
55
  end
@@ -72,6 +74,9 @@ module Enumerize
72
74
 
73
75
  def _validate_enumerized_attributes
74
76
  self.class.enumerized_attributes.each do |attr|
77
+ skip_validations = Utils.call_if_callable(attr.skip_validations_value, self)
78
+ next if skip_validations
79
+
75
80
  value = read_attribute_for_validation(attr.name)
76
81
  next if value.blank?
77
82
 
@@ -85,27 +90,26 @@ module Enumerize
85
90
 
86
91
  def _set_default_value_for_enumerized_attributes
87
92
  self.class.enumerized_attributes.each do |attr|
88
- next if attr.default_value.nil?
89
- begin
90
- if respond_to?(attr.name)
91
- attr_value = public_send(attr.name)
92
- else
93
- next
94
- end
95
-
96
- value_for_validation = _enumerized_values_for_validation[attr.name.to_s]
93
+ _set_default_value_for_enumerized_attribute(attr)
94
+ end
95
+ end
97
96
 
98
- if (!attr_value || attr_value.empty?) && (!value_for_validation || value_for_validation.empty?)
99
- value = attr.default_value
97
+ def _set_default_value_for_enumerized_attribute(attr)
98
+ return if attr.default_value.nil?
99
+ begin
100
+ if respond_to?(attr.name)
101
+ attr_value = public_send(attr.name)
102
+ else
103
+ return
104
+ end
100
105
 
101
- if value.respond_to?(:call)
102
- value = value.arity == 0 ? value.call : value.call(self)
103
- end
106
+ value_for_validation = _enumerized_values_for_validation[attr.name.to_s]
104
107
 
105
- public_send("#{attr.name}=", value)
106
- end
107
- rescue ActiveModel::MissingAttributeError
108
+ if (!attr_value || attr_value.empty?) && (!value_for_validation || value_for_validation.empty?)
109
+ value = Utils.call_if_callable(attr.default_value, self)
110
+ public_send("#{attr.name}=", value)
108
111
  end
112
+ rescue ActiveModel::MissingAttributeError
109
113
  end
110
114
  end
111
115
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support/concern'
2
4
 
3
5
  module Enumerize
@@ -5,7 +7,8 @@ module Enumerize
5
7
  module FormtasticFormBuilderExtension
6
8
 
7
9
  def input(method, options={})
8
- klass = object.class
10
+ enumerized_object = convert_to_model(object)
11
+ klass = enumerized_object.class
9
12
 
10
13
  if klass.respond_to?(:enumerized_attributes) && (attr = klass.enumerized_attributes[method])
11
14
  options[:collection] ||= attr.options
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Enumerize
2
4
  module Hooks
3
5
  module SequelDataset
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support/concern'
2
4
 
3
5
  module Enumerize
@@ -17,7 +19,8 @@ module Enumerize
17
19
  private
18
20
 
19
21
  def add_input_options_for_enumerized_attribute(attribute_name, options)
20
- klass = object.class
22
+ enumerized_object = convert_to_model(object)
23
+ klass = enumerized_object.class
21
24
 
22
25
  if klass.respond_to?(:enumerized_attributes) && (attr = klass.enumerized_attributes[attribute_name])
23
26
  options[:collection] ||= attr.options
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support/concern'
2
4
 
3
5
  module Enumerize
@@ -5,7 +7,9 @@ module Enumerize
5
7
  module UniquenessValidator
6
8
 
7
9
  def validate_each(record, name, value)
8
- if record.class.respond_to?(:enumerized_attributes) && (attr = record.class.enumerized_attributes[name])
10
+ klass = record.to_model.class
11
+
12
+ if klass.respond_to?(:enumerized_attributes) && (attr = klass.enumerized_attributes[name])
9
13
  value = attr.find_value(value).try(:value)
10
14
  end
11
15
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Enumerize
2
4
  module Integrations
3
5
  module RailsAdmin
@@ -7,7 +9,7 @@ module Enumerize
7
9
 
8
10
  _enumerize_module.module_eval <<-RUBY, __FILE__, __LINE__ + 1
9
11
  def #{name}_enum
10
- self.class.enumerized_attributes[:#{name}].values.map{|v| [v.text, v.value]}
12
+ self.class.enumerized_attributes[:#{name}].options
11
13
  end
12
14
  RUBY
13
15
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Enumerize
2
4
  module Integrations
3
5
  module RSpec
@@ -108,7 +110,7 @@ module Enumerize
108
110
 
109
111
  def matches_predicates?
110
112
  if expected_predicates.is_a?(TrueClass)
111
- subject.respond_to?("#{sorted_values.first}?")
113
+ subject.respond_to?("#{enumerized_values.first}?")
112
114
  else
113
115
  subject.respond_to?("#{expected_attr}_#{attributes.values.first}?")
114
116
  end
@@ -119,8 +121,11 @@ module Enumerize
119
121
  end
120
122
 
121
123
  def matches_scope?
122
- if expected_scope.is_a?(TrueClass)
124
+ case expected_scope
125
+ when TrueClass
123
126
  subject_class.respond_to?("with_#{expected_attr}")
127
+ when :shallow
128
+ enumerized_values.all? { |value| subject_class.respond_to?(value) }
124
129
  else
125
130
  subject_class.respond_to?(expected_scope[:scope])
126
131
  end
@@ -1,3 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'rspec/matchers'
1
4
  require 'enumerize/integrations/rspec/matcher'
2
5
 
3
6
  module Enumerize
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Enumerize
2
4
  class Module < ::Module
3
5
  attr_reader :_class_methods
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Enumerize
2
4
  module ModuleAttributes
3
5
  def included(base)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Enumerize
2
4
  module MongoidSupport
3
5
  def enumerize(name, options={})
@@ -5,9 +7,30 @@ module Enumerize
5
7
 
6
8
  _enumerize_module.dependent_eval do
7
9
  if self < ::Mongoid::Document
10
+ include InstanceMethods
11
+
8
12
  after_initialize :_set_default_value_for_enumerized_attributes
9
13
  end
10
14
  end
11
15
  end
16
+
17
+ module InstanceMethods
18
+ def reload
19
+ reloaded = super
20
+
21
+ reloaded.class.enumerized_attributes.each do |attr|
22
+ reloaded.send("#{attr.name}=", reloaded[attr.name])
23
+ end
24
+
25
+ reloaded
26
+ end
27
+
28
+ private
29
+
30
+ def _set_default_value_for_enumerized_attribute(attr)
31
+ super
32
+ rescue Mongoid::Errors::AttributeNotLoaded
33
+ end
34
+ end
12
35
  end
13
36
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Enumerize
2
4
  module Predicatable
3
5
  def respond_to_missing?(method, include_private=false)
@@ -15,7 +17,7 @@ module Enumerize
15
17
  end
16
18
 
17
19
  def predicate_method?(method)
18
- method[-1] == '?' && @attr.values.include?(method[0..-2])
20
+ method[-1] == '?' && @attr && @attr.value?(method[0..-2])
19
21
  end
20
22
  end
21
23
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support/core_ext/module/delegation'
2
4
 
3
5
  module Enumerize
@@ -67,8 +69,22 @@ module Enumerize
67
69
  end
68
70
 
69
71
  def build(klass)
72
+ warn_on_already_defined_methods
73
+
70
74
  klass.delegate(*names, to: @attr.name, prefix: @options[:prefix], allow_nil: true)
71
75
  end
76
+
77
+ def warn_on_already_defined_methods
78
+ names.each do |name|
79
+ method_name = [@options[:prefix], name].compact.join('_')
80
+
81
+ if @attr.klass.respond_to?(method_name)
82
+ warn(
83
+ "Predicate method `#{name}` is already defined as #{@attr.klass.name}##{name}. Use enumerize's :prefix option to avoid it"
84
+ )
85
+ end
86
+ end
87
+ end
72
88
  end
73
89
  end
74
90
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Enumerize
2
4
  module Scope
3
5
  module ActiveRecord
@@ -16,6 +18,8 @@ module Enumerize
16
18
  private
17
19
 
18
20
  def _define_activerecord_scope_methods!(name, options)
21
+ return _define_activerecord_shallow_scopes!(name) if options[:scope] == :shallow
22
+
19
23
  scope_name = options[:scope] == true ? "with_#{name}" : options[:scope]
20
24
 
21
25
  define_singleton_method scope_name do |*values|
@@ -32,6 +36,18 @@ module Enumerize
32
36
  end
33
37
  end
34
38
  end
39
+
40
+ def _define_activerecord_shallow_scopes!(attribute_name)
41
+ enumerized_attributes[attribute_name].each_value do |value_obj|
42
+ define_singleton_method(value_obj) do
43
+ where(attribute_name => value_obj.value)
44
+ end
45
+
46
+ define_singleton_method("not_#{value_obj}") do
47
+ where.not(attribute_name => value_obj.value)
48
+ end
49
+ end
50
+ end
35
51
  end
36
52
  end
37
53
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Enumerize
2
4
  module Scope
3
5
  module Mongoid
@@ -16,6 +18,7 @@ module Enumerize
16
18
  private
17
19
 
18
20
  def _define_mongoid_scope_methods!(name, options)
21
+ return _define_mongoid_shallow_scopes!(name) if options[:scope] == :shallow
19
22
  scope_name = options[:scope] == true ? "with_#{name}" : options[:scope]
20
23
 
21
24
  define_singleton_method scope_name do |*values|
@@ -30,6 +33,18 @@ module Enumerize
30
33
  end
31
34
  end
32
35
  end
36
+
37
+ def _define_mongoid_shallow_scopes!(attribute_name)
38
+ enumerized_attributes[attribute_name].each_value do |value_obj|
39
+ define_singleton_method(value_obj) do
40
+ self.in(attribute_name => value_obj.value)
41
+ end
42
+
43
+ define_singleton_method("not_#{value_obj}") do
44
+ self.not_in(attribute_name => value_obj.value)
45
+ end
46
+ end
47
+ end
33
48
  end
34
49
  end
35
50
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Enumerize
2
4
  module Scope
3
5
  module Sequel
@@ -18,6 +20,8 @@ module Enumerize
18
20
  private
19
21
 
20
22
  def _define_sequel_scope_methods!(name, options)
23
+ return _define_sequel_shallow_scopes!(name) if options[:scope] == :shallow
24
+
21
25
  klass = self
22
26
  scope_name = options[:scope] == true ? "with_#{name}" : options[:scope]
23
27
 
@@ -35,6 +39,18 @@ module Enumerize
35
39
  end
36
40
  end
37
41
  end
42
+
43
+ def _define_sequel_shallow_scopes!(attribute_name)
44
+ enumerized_attributes[attribute_name].each_value do |value_obj|
45
+ def_dataset_method(value_obj) do
46
+ where(attribute_name => value_obj.value.to_s)
47
+ end
48
+
49
+ def_dataset_method("not_#{value_obj}") do
50
+ exclude(attribute_name => value_obj.value.to_s)
51
+ end
52
+ end
53
+ end
38
54
  end
39
55
  end
40
56
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Enumerize
2
4
  module SequelSupport
3
5
  def enumerize(name, options={})
@@ -17,8 +19,11 @@ module Enumerize
17
19
  module InstanceMethods
18
20
  def validate
19
21
  super
20
-
22
+
21
23
  self.class.enumerized_attributes.each do |attr|
24
+ skip_validations = Utils.call_if_callable(attr.skip_validations_value, self)
25
+ next if skip_validations
26
+
22
27
  value = read_attribute_for_validation(attr.name)
23
28
  next if value.blank?
24
29
 
@@ -38,13 +43,13 @@ module Enumerize
38
43
  if defined?(Sequel::Plugins::Serialization::InstanceMethods)
39
44
  modules = self.class.ancestors
40
45
  plugin_idx = modules.index(Sequel::Plugins::Serialization::InstanceMethods)
41
-
46
+
42
47
  if plugin_idx && plugin_idx < modules.index(Enumerize::SequelSupport::InstanceMethods)
43
48
  abort "ERROR: You need to enable the Sequel serialization plugin before calling any enumerize methods on a model."
44
49
  end
45
-
50
+
46
51
  plugin_idx = modules.index(Sequel::Plugins::ValidationHelpers::InstanceMethods)
47
-
52
+
48
53
  if plugin_idx && plugin_idx < modules.index(Enumerize::SequelSupport::InstanceMethods)
49
54
  abort "ERROR: You need to enable the Sequel validation_helpers plugin before calling any enumerize methods on a model."
50
55
  end
data/lib/enumerize/set.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support/core_ext/module/delegation'
2
4
 
3
5
  module Enumerize
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Enumerize
4
+ module Utils
5
+ class << self
6
+ def call_if_callable(value, param = nil)
7
+ return value unless value.respond_to?(:call)
8
+ value.arity == 0 ? value.call : value.call(param)
9
+ end
10
+ end
11
+ end
12
+ end