enumerize 0.3.0 → 2.3.1

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 +7 -0
  2. data/.gitignore +5 -1
  3. data/.rspec +2 -0
  4. data/.travis.yml +38 -11
  5. data/CHANGELOG.md +258 -0
  6. data/Gemfile +5 -11
  7. data/Gemfile.global +20 -0
  8. data/Gemfile.mongo_mapper +7 -0
  9. data/Gemfile.rails42 +7 -0
  10. data/Gemfile.rails50 +7 -0
  11. data/Gemfile.rails52 +7 -0
  12. data/README.md +405 -17
  13. data/Rakefile +7 -1
  14. data/enumerize.gemspec +6 -3
  15. data/lib/enumerize/activemodel.rb +47 -0
  16. data/lib/enumerize/activerecord.rb +127 -2
  17. data/lib/enumerize/attribute.rb +167 -7
  18. data/lib/enumerize/attribute_map.rb +4 -0
  19. data/lib/enumerize/base.rb +60 -61
  20. data/lib/enumerize/hooks/formtastic.rb +11 -12
  21. data/lib/enumerize/hooks/sequel_dataset.rb +17 -0
  22. data/lib/enumerize/hooks/simple_form.rb +21 -8
  23. data/lib/enumerize/hooks/uniqueness.rb +22 -0
  24. data/lib/enumerize/integrations/rails_admin.rb +18 -0
  25. data/lib/enumerize/integrations/rspec/matcher.rb +161 -0
  26. data/lib/enumerize/integrations/rspec.rb +19 -0
  27. data/lib/enumerize/module.rb +33 -0
  28. data/lib/enumerize/module_attributes.rb +3 -2
  29. data/lib/enumerize/mongoid.rb +29 -0
  30. data/lib/enumerize/predicatable.rb +23 -0
  31. data/lib/enumerize/predicates.rb +76 -0
  32. data/lib/enumerize/scope/activerecord.rb +49 -0
  33. data/lib/enumerize/scope/mongoid.rb +46 -0
  34. data/lib/enumerize/scope/sequel.rb +52 -0
  35. data/lib/enumerize/sequel.rb +62 -0
  36. data/lib/enumerize/set.rb +81 -0
  37. data/lib/enumerize/utils.rb +12 -0
  38. data/lib/enumerize/value.rb +19 -46
  39. data/lib/enumerize/version.rb +3 -1
  40. data/lib/enumerize.rb +56 -4
  41. data/lib/sequel/plugins/enumerize.rb +18 -0
  42. data/spec/enumerize/integrations/rspec/matcher_spec.rb +260 -0
  43. data/spec/spec_helper.rb +30 -0
  44. data/test/activemodel_test.rb +114 -0
  45. data/test/activerecord_test.rb +542 -8
  46. data/test/attribute_map_test.rb +2 -0
  47. data/test/attribute_test.rb +102 -4
  48. data/test/base_test.rb +61 -39
  49. data/test/formtastic_test.rb +102 -17
  50. data/test/module_attributes_test.rb +25 -2
  51. data/test/mongo_mapper_test.rb +84 -0
  52. data/test/mongoid_test.rb +98 -7
  53. data/test/multiple_test.rb +59 -0
  54. data/test/predicates_test.rb +65 -0
  55. data/test/rails_admin_test.rb +27 -0
  56. data/test/sequel_test.rb +341 -0
  57. data/test/set_test.rb +166 -0
  58. data/test/simple_form_test.rb +110 -4
  59. data/test/support/mock_controller.rb +11 -1
  60. data/test/support/shared_enums.rb +43 -0
  61. data/test/support/view_test_helper.rb +6 -0
  62. data/test/test_helper.rb +25 -6
  63. data/test/value_test.rb +102 -13
  64. metadata +62 -28
  65. data/gemfiles/Gemfile-ar-3.1.x +0 -13
@@ -1,7 +1,132 @@
1
- require 'active_support/concern'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Enumerize
4
- module ActiveRecord
4
+ module ActiveRecordSupport
5
+ def enumerize(name, options={})
6
+ super
5
7
 
8
+ _enumerize_module.dependent_eval do
9
+ if self < ::ActiveRecord::Base
10
+ include InstanceMethods
11
+
12
+ const_get(:ActiveRecord_Relation).include(RelationMethods)
13
+ const_get(:ActiveRecord_AssociationRelation).include(RelationMethods)
14
+ const_get(:ActiveRecord_Associations_CollectionProxy).include(RelationMethods)
15
+
16
+ # Since Rails use `allocate` method on models and initializes them with `init_with` method.
17
+ # This way `initialize` method is not being called, but `after_initialize` callback always gets triggered.
18
+ after_initialize :_set_default_value_for_enumerized_attributes
19
+
20
+ # https://github.com/brainspec/enumerize/issues/111
21
+ require 'enumerize/hooks/uniqueness'
22
+
23
+ unless options[:multiple]
24
+ decorate_attribute_type(name, :enumerize) do |subtype|
25
+ Type.new(enumerized_attributes[name], subtype)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
31
+
32
+ module InstanceMethods
33
+ # https://github.com/brainspec/enumerize/issues/74
34
+ def write_attribute(attr_name, value, *options)
35
+ if self.class.enumerized_attributes[attr_name]
36
+ _enumerized_values_for_validation[attr_name.to_s] = value
37
+ end
38
+
39
+ super
40
+ end
41
+
42
+ # Support multiple enumerized attributes
43
+ def becomes(klass)
44
+ became = super
45
+ klass.enumerized_attributes.each do |attr|
46
+ # Rescue when column associated to the enum does not exist.
47
+ begin
48
+ became.send("#{attr.name}=", send(attr.name))
49
+ rescue ActiveModel::MissingAttributeError
50
+ end
51
+ end
52
+
53
+ became
54
+ end
55
+
56
+ def reload(options = nil)
57
+ reloaded = super
58
+
59
+ reloaded.class.enumerized_attributes.each do |attr|
60
+ begin
61
+ # Checks first if the enumerized attribute is in ActiveRecord::Store
62
+ store_attr, _ = reloaded.class.stored_attributes.detect do |store_attr, keys|
63
+ keys.include?(attr.name)
64
+ end
65
+
66
+ if store_attr.present?
67
+ reloaded.send("#{attr.name}=", reloaded.send(store_attr).with_indifferent_access[attr.name])
68
+ else
69
+ reloaded.send("#{attr.name}=", reloaded[attr.name])
70
+ end
71
+ rescue ActiveModel::MissingAttributeError
72
+ end
73
+ end
74
+
75
+ reloaded
76
+ end
77
+ end
78
+
79
+ module RelationMethods
80
+ def update_all(updates)
81
+ if updates.is_a?(Hash)
82
+ enumerized_attributes.each do |attr|
83
+ next if updates[attr.name].blank? || attr.kind_of?(Enumerize::Multiple)
84
+ enumerize_value = attr.find_value(updates[attr.name])
85
+ updates[attr.name] = enumerize_value && enumerize_value.value
86
+ end
87
+ end
88
+
89
+ super(updates)
90
+ end
91
+ end
92
+
93
+ class Type < ActiveRecord::Type::Value
94
+ delegate :type, to: :@subtype
95
+
96
+ def initialize(attr, subtype)
97
+ @attr = attr
98
+ @subtype = subtype
99
+ end
100
+
101
+ def serialize(value)
102
+ v = @attr.find_value(value)
103
+ (v && v.value) || value
104
+ end
105
+
106
+ alias type_cast_for_database serialize
107
+
108
+ def deserialize(value)
109
+ @attr.find_value(value)
110
+ end
111
+
112
+ alias type_cast_from_database deserialize
113
+
114
+ def as_json(options = nil)
115
+ {attr: @attr.name, subtype: @subtype}.as_json(options)
116
+ end
117
+
118
+ def encode_with(coder)
119
+ coder[:class_name] = @attr.klass.name
120
+ coder[:attr_name] = @attr.name
121
+ coder[:subtype] = @subtype
122
+ end
123
+
124
+ def init_with(coder)
125
+ initialize(
126
+ coder[:class_name].constantize.enumerized_attributes[coder[:attr_name]],
127
+ coder[:subtype]
128
+ )
129
+ end
130
+ end
6
131
  end
7
132
  end
@@ -1,32 +1,192 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Enumerize
2
4
  class Attribute
3
- attr_reader :name, :values, :default_value
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]
9
+ raise ArgumentError, ':scope option does not work with option :multiple' if options[:multiple] && options[:scope]
10
+
11
+ extend Multiple if options[:multiple]
7
12
 
8
13
  @klass = klass
9
14
  @name = name.to_sym
10
- @values = Array(options[:in]).map { |v| Value.new(self, *v) }
15
+
16
+ if options[:i18n_scope]
17
+ raise ArgumentError, ':i18n_scope option accepts only String or Array of strings' unless Array(options[:i18n_scope]).all? { |s| s.is_a?(String) }
18
+ @i18n_scope = options[:i18n_scope]
19
+ end
20
+
21
+ value_class = options.fetch(:value_class, Value)
22
+ @values = Array(options[:in]).map { |v| value_class.new(self, *v).freeze }
23
+
11
24
  @value_hash = Hash[@values.map { |v| [v.value.to_s, v] }]
12
25
  @value_hash.merge! Hash[@values.map { |v| [v.to_s, v] }]
13
26
 
14
27
  if options[:default]
15
- @default_value = find_value(options[:default])
28
+ @default_value = find_default_value(options[:default])
16
29
  raise ArgumentError, 'invalid default value' unless @default_value
17
30
  end
31
+
32
+ @skip_validations_value = options.fetch(:skip_validations, false)
33
+ end
34
+
35
+ def find_default_value(value)
36
+ if value.respond_to?(:call)
37
+ value
38
+ else
39
+ find_value(value)
40
+ end
18
41
  end
19
42
 
20
43
  def find_value(value)
21
44
  @value_hash[value.to_s] unless value.nil?
22
45
  end
23
46
 
24
- def i18n_suffix
25
- @klass.model_name.i18n_key if @klass.respond_to?(:model_name)
47
+ def find_values(*values)
48
+ values.map { |value| find_value(value) }.compact
49
+ end
50
+
51
+ def each_value
52
+ values.each { |value| yield value }
53
+ end
54
+
55
+ def i18n_scopes
56
+ @i18n_scopes ||= if i18n_scope
57
+ Array(i18n_scope)
58
+ elsif @klass.respond_to?(:model_name)
59
+ ["enumerize.#{@klass.model_name.i18n_key}.#{name}"]
60
+ else
61
+ []
62
+ end
63
+ end
64
+
65
+ def options(options = {})
66
+ values = if options.empty?
67
+ @values
68
+ else
69
+ raise ArgumentError, 'Options cannot have both :only and :except' if options[:only] && options[:except]
70
+
71
+ only = Array(options[:only]).map(&:to_s)
72
+ except = Array(options[:except]).map(&:to_s)
73
+
74
+ @values.reject do |value|
75
+ if options[:only]
76
+ !only.include?(value)
77
+ elsif options[:except]
78
+ except.include?(value)
79
+ end
80
+ end
81
+ end
82
+
83
+ values.map { |v| [v.text, v.to_s] }
84
+ end
85
+
86
+ def respond_to_missing?(method, include_private=false)
87
+ @value_hash.include?(method.to_s) || super
88
+ end
89
+
90
+ def define_methods!(mod)
91
+ mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
92
+ def #{name}
93
+ if defined?(super)
94
+ self.class.enumerized_attributes[:#{name}].find_value(super)
95
+ elsif respond_to?(:read_attribute)
96
+ self.class.enumerized_attributes[:#{name}].find_value(read_attribute(:#{name}))
97
+ else
98
+ if defined?(@#{name})
99
+ self.class.enumerized_attributes[:#{name}].find_value(@#{name})
100
+ else
101
+ @#{name} = nil
102
+ end
103
+ end
104
+ end
105
+
106
+ def #{name}=(new_value)
107
+ allowed_value_or_nil = self.class.enumerized_attributes[:#{name}].find_value(new_value)
108
+ allowed_value_or_nil = allowed_value_or_nil.value unless allowed_value_or_nil.nil?
109
+
110
+ if defined?(super)
111
+ super allowed_value_or_nil
112
+ elsif respond_to?(:write_attribute, true)
113
+ write_attribute '#{name}', allowed_value_or_nil
114
+ else
115
+ @#{name} = allowed_value_or_nil
116
+ end
117
+
118
+ _enumerized_values_for_validation['#{name}'] = new_value.nil? ? nil : new_value.to_s
119
+
120
+ allowed_value_or_nil
121
+ end
122
+
123
+ def #{name}_text
124
+ self.#{name} && self.#{name}.text
125
+ end
126
+
127
+ def #{name}_value
128
+ self.#{name} && self.#{name}.value
129
+ end
130
+ RUBY
131
+ end
132
+
133
+ private
134
+
135
+ def method_missing(method)
136
+ if @value_hash.include?(method.to_s)
137
+ find_value(method)
138
+ else
139
+ super
140
+ end
141
+ end
142
+ end
143
+
144
+ module Multiple
145
+ def find_default_value(value)
146
+ if value.respond_to?(:call)
147
+ value
148
+ else
149
+ find_values(*value)
150
+ end
26
151
  end
27
152
 
28
- def options
29
- @values.map { |v| [v.text, v.to_s] }
153
+ def define_methods!(mod)
154
+ mod.module_eval <<-RUBY, __FILE__, __LINE__ + 1
155
+ def #{name}
156
+ unless defined?(@_#{name}_enumerized_set)
157
+ if defined?(super)
158
+ self.#{name} = super
159
+ elsif respond_to?(:read_attribute)
160
+ self.#{name} = read_attribute(:#{name})
161
+ else
162
+ if defined?(@#{name})
163
+ self.#{name} = @#{name}
164
+ else
165
+ self.#{name} = []
166
+ end
167
+ end
168
+ end
169
+
170
+ @_#{name}_enumerized_set
171
+ end
172
+
173
+ def #{name}=(values)
174
+ @_#{name}_enumerized_set = Enumerize::Set.new(self, self.class.enumerized_attributes[:#{name}], values)
175
+ raw_values = #{name}.values.map(&:value)
176
+
177
+ if defined?(super)
178
+ super raw_values
179
+ elsif respond_to?(:write_attribute, true)
180
+ write_attribute '#{name}', raw_values
181
+ else
182
+ @#{name} = raw_values
183
+ end
184
+
185
+ _enumerized_values_for_validation['#{name}'] = values.respond_to?(:map) ? values.reject(&:blank?).map(&:to_s) : values
186
+
187
+ #{name}
188
+ end
189
+ RUBY
30
190
  end
31
191
  end
32
192
  end
@@ -1,5 +1,9 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Enumerize
2
4
  class AttributeMap
5
+ attr_reader :attributes
6
+
3
7
  def initialize
4
8
  @attributes = {}
5
9
  @dependants = []
@@ -1,8 +1,15 @@
1
- require 'active_support/concern'
1
+ # frozen_string_literal: true
2
2
 
3
3
  module Enumerize
4
4
  module Base
5
- extend ActiveSupport::Concern
5
+ def self.included(base)
6
+ base.extend ClassMethods
7
+ base.singleton_class.prepend ClassMethods::Hook
8
+
9
+ if base.respond_to?(:validate)
10
+ base.validate :_validate_enumerized_attributes
11
+ end
12
+ end
6
13
 
7
14
  module ClassMethods
8
15
  def enumerize(name, options={})
@@ -17,90 +24,45 @@ module Enumerize
17
24
  RUBY
18
25
  end
19
26
 
20
- _define_enumerize_attribute(attr)
21
-
22
- _enumerize_module.module_eval <<-RUBY, __FILE__, __LINE__ + 1
23
- def #{attr.name}_text
24
- #{attr.name} && #{attr.name}.text
25
- end
26
- RUBY
27
-
28
- if respond_to?(:validates)
29
- validates name, :inclusion => {:in => enumerized_attributes[name].values.map(&:to_s), :allow_nil => true, :allow_blank => true}
30
- end
27
+ attr.define_methods!(_enumerize_module)
31
28
  end
32
29
 
33
30
  def enumerized_attributes
34
31
  @enumerized_attributes ||= AttributeMap.new
35
32
  end
36
33
 
37
- def inherited(subclass)
38
- enumerized_attributes.add_dependant subclass.enumerized_attributes
39
- super
34
+ module Hook
35
+ def inherited(subclass)
36
+ enumerized_attributes.add_dependant subclass.enumerized_attributes
37
+ super subclass
38
+ end
40
39
  end
41
40
 
42
41
  private
43
42
 
44
43
  def _enumerize_module
45
44
  @_enumerize_module ||= begin
46
- mod = Module.new do
47
- @_class_methods = Module.new
48
- class << self
49
- attr_reader :_class_methods
50
- end
51
- end
45
+ mod = Module.new
52
46
  include mod
53
- extend mod._class_methods
54
47
  mod
55
48
  end
56
49
  end
57
-
58
- def _define_enumerize_attribute(attr)
59
- _enumerize_module.module_eval <<-RUBY, __FILE__, __LINE__ + 1
60
- def #{attr.name}
61
- if defined?(super)
62
- self.class.enumerized_attributes[:#{attr.name}].find_value(super)
63
- elsif respond_to?(:read_attribute, true)
64
- self.class.enumerized_attributes[:#{attr.name}].find_value(read_attribute(:#{attr.name}))
65
- else
66
- if defined?(@#{attr.name})
67
- self.class.enumerized_attributes[:#{attr.name}].find_value(@#{attr.name})
68
- else
69
- @#{attr.name} = nil
70
- end
71
- end
72
- end
73
-
74
- def #{attr.name}=(new_value)
75
- _enumerized_values_for_validation[:#{attr.name}] = new_value.nil? ? nil : new_value.to_s
76
-
77
- allowed_value_or_nil = self.class.enumerized_attributes[:#{attr.name}].find_value(new_value)
78
- allowed_value_or_nil = allowed_value_or_nil.value unless allowed_value_or_nil.nil?
79
-
80
- if defined?(super)
81
- super allowed_value_or_nil
82
- elsif respond_to?(:write_attribute, true)
83
- write_attribute :#{attr.name}, allowed_value_or_nil
84
- else
85
- @#{attr.name} = allowed_value_or_nil
86
- end
87
- end
88
- RUBY
89
- end
90
50
  end
91
51
 
92
52
  def initialize(*)
93
53
  super
94
- self.class.enumerized_attributes.each do |attr|
95
- public_send("#{attr.name}=", attr.default_value) unless _enumerized_values_for_validation.key?(attr.name)
96
- end
54
+ _set_default_value_for_enumerized_attributes
97
55
  end
98
56
 
99
57
  def read_attribute_for_validation(key)
100
- if self.class.enumerized_attributes[key].instance_of?(Enumerize::Attribute) && _enumerized_values_for_validation.has_key?(key)
58
+ key = key.to_s
59
+
60
+ if _enumerized_values_for_validation.has_key?(key)
101
61
  _enumerized_values_for_validation[key]
102
- else
62
+ elsif defined?(super)
103
63
  super
64
+ else
65
+ send(key)
104
66
  end
105
67
  end
106
68
 
@@ -109,5 +71,42 @@ module Enumerize
109
71
  def _enumerized_values_for_validation
110
72
  @_enumerized_values_for_validation ||= {}
111
73
  end
74
+
75
+ def _validate_enumerized_attributes
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
+
80
+ value = read_attribute_for_validation(attr.name)
81
+ next if value.blank?
82
+
83
+ if attr.kind_of? Multiple
84
+ errors.add attr.name unless value.respond_to?(:all?) && value.all? { |v| v.blank? || attr.find_value(v) }
85
+ else
86
+ errors.add attr.name, :inclusion unless attr.find_value(value)
87
+ end
88
+ end
89
+ end
90
+
91
+ def _set_default_value_for_enumerized_attributes
92
+ self.class.enumerized_attributes.each do |attr|
93
+ next if attr.default_value.nil?
94
+ begin
95
+ if respond_to?(attr.name)
96
+ attr_value = public_send(attr.name)
97
+ else
98
+ next
99
+ end
100
+
101
+ value_for_validation = _enumerized_values_for_validation[attr.name.to_s]
102
+
103
+ if (!attr_value || attr_value.empty?) && (!value_for_validation || value_for_validation.empty?)
104
+ value = Utils.call_if_callable(attr.default_value, self)
105
+ public_send("#{attr.name}=", value)
106
+ end
107
+ rescue ActiveModel::MissingAttributeError
108
+ end
109
+ end
110
+ end
112
111
  end
113
112
  end
@@ -1,28 +1,27 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support/concern'
2
4
 
3
5
  module Enumerize
4
6
  module Hooks
5
7
  module FormtasticFormBuilderExtension
6
- extend ActiveSupport::Concern
7
8
 
8
- included do
9
- alias_method_chain :input, :enumerize
10
- end
9
+ def input(method, options={})
10
+ enumerized_object = convert_to_model(object)
11
+ klass = enumerized_object.class
11
12
 
12
- def input_with_enumerize(method, options={})
13
- klass = object.class
14
13
  if klass.respond_to?(:enumerized_attributes) && (attr = klass.enumerized_attributes[method])
15
14
  options[:collection] ||= attr.options
15
+
16
+ if attr.kind_of?(Enumerize::Multiple) && options[:as] != :check_boxes
17
+ options[:input_html] = options.fetch(:input_html, {}).merge(:multiple => true)
18
+ end
16
19
  end
17
20
 
18
- input_without_enumerize(method, options)
21
+ super(method, options)
19
22
  end
20
23
  end
21
24
  end
22
25
  end
23
26
 
24
- if defined? ::Formtastic::SemanticFormBuilder
25
- ::Formtastic::SemanticFormBuilder.send :include, Enumerize::Hooks::FormtasticFormBuilderExtension
26
- else
27
- ::Formtastic::FormBuilder.send :include, Enumerize::Hooks::FormtasticFormBuilderExtension
28
- end
27
+ ::Formtastic::FormBuilder.send :prepend, Enumerize::Hooks::FormtasticFormBuilderExtension
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Enumerize
4
+ module Hooks
5
+ module SequelDataset
6
+ def literal_append(sql, v)
7
+ if v.is_a?(Enumerize::Value)
8
+ super(sql, v.value)
9
+ else
10
+ super(sql, v)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
16
+
17
+ ::Sequel::Dataset.send :prepend, Enumerize::Hooks::SequelDataset
@@ -1,24 +1,37 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_support/concern'
2
4
 
3
5
  module Enumerize
4
6
  module Hooks
5
7
  module SimpleFormBuilderExtension
6
- extend ActiveSupport::Concern
7
8
 
8
- included do
9
- alias_method_chain :input, :enumerize
9
+ def input(attribute_name, options={}, &block)
10
+ add_input_options_for_enumerized_attribute(attribute_name, options)
11
+ super(attribute_name, options, &block)
12
+ end
13
+
14
+ def input_field(attribute_name, options={})
15
+ add_input_options_for_enumerized_attribute(attribute_name, options)
16
+ super(attribute_name, options)
10
17
  end
11
18
 
12
- def input_with_enumerize(attribute_name, options={}, &block)
13
- klass = object.class
19
+ private
20
+
21
+ def add_input_options_for_enumerized_attribute(attribute_name, options)
22
+ enumerized_object = convert_to_model(object)
23
+ klass = enumerized_object.class
24
+
14
25
  if klass.respond_to?(:enumerized_attributes) && (attr = klass.enumerized_attributes[attribute_name])
15
26
  options[:collection] ||= attr.options
16
- end
17
27
 
18
- input_without_enumerize(attribute_name, options, &block)
28
+ if attr.kind_of?(Enumerize::Multiple) && options[:as] != :check_boxes
29
+ options[:input_html] = options.fetch(:input_html, {}).merge(:multiple => true)
30
+ end
31
+ end
19
32
  end
20
33
  end
21
34
  end
22
35
  end
23
36
 
24
- ::SimpleForm::FormBuilder.send :include, Enumerize::Hooks::SimpleFormBuilderExtension
37
+ ::SimpleForm::FormBuilder.send :prepend, Enumerize::Hooks::SimpleFormBuilderExtension
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'active_support/concern'
4
+
5
+ module Enumerize
6
+ module Hooks
7
+ module UniquenessValidator
8
+
9
+ def validate_each(record, name, value)
10
+ klass = record.to_model.class
11
+
12
+ if klass.respond_to?(:enumerized_attributes) && (attr = klass.enumerized_attributes[name])
13
+ value = attr.find_value(value).try(:value)
14
+ end
15
+
16
+ super(record, name, value)
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ ::ActiveRecord::Validations::UniquenessValidator.send :prepend, Enumerize::Hooks::UniquenessValidator
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Enumerize
4
+ module Integrations
5
+ module RailsAdmin
6
+
7
+ def enumerize(name, options={})
8
+ super
9
+
10
+ _enumerize_module.module_eval <<-RUBY, __FILE__, __LINE__ + 1
11
+ def #{name}_enum
12
+ self.class.enumerized_attributes[:#{name}].options
13
+ end
14
+ RUBY
15
+ end
16
+ end
17
+ end
18
+ end