enumerize 2.0.0 → 2.7.0

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