careacademy-enumerize 2.8.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.
- checksums.yaml +7 -0
- data/.github/workflows/ruby.yml +69 -0
- data/.gitignore +23 -0
- data/.rspec +2 -0
- data/CHANGELOG.md +327 -0
- data/Gemfile +6 -0
- data/Gemfile.global +12 -0
- data/Gemfile.mongo_mapper +6 -0
- data/Gemfile.rails60 +6 -0
- data/Gemfile.rails61 +6 -0
- data/Gemfile.rails70 +9 -0
- data/Gemfile.railsmaster +5 -0
- data/MIT-LICENSE +22 -0
- data/README.md +641 -0
- data/Rakefile +17 -0
- data/enumerize.gemspec +22 -0
- data/lib/enumerize/activemodel.rb +47 -0
- data/lib/enumerize/activerecord.rb +142 -0
- data/lib/enumerize/attribute.rb +192 -0
- data/lib/enumerize/attribute_map.rb +40 -0
- data/lib/enumerize/base.rb +112 -0
- data/lib/enumerize/hooks/formtastic.rb +27 -0
- data/lib/enumerize/hooks/sequel_dataset.rb +17 -0
- data/lib/enumerize/hooks/simple_form.rb +37 -0
- data/lib/enumerize/hooks/uniqueness.rb +22 -0
- data/lib/enumerize/integrations/rails_admin.rb +18 -0
- data/lib/enumerize/integrations/rspec/matcher.rb +164 -0
- data/lib/enumerize/integrations/rspec.rb +19 -0
- data/lib/enumerize/module.rb +33 -0
- data/lib/enumerize/module_attributes.rb +12 -0
- data/lib/enumerize/mongoid.rb +29 -0
- data/lib/enumerize/predicatable.rb +23 -0
- data/lib/enumerize/predicates.rb +76 -0
- data/lib/enumerize/scope/activerecord.rb +53 -0
- data/lib/enumerize/scope/mongoid.rb +50 -0
- data/lib/enumerize/scope/sequel.rb +56 -0
- data/lib/enumerize/sequel.rb +62 -0
- data/lib/enumerize/set.rb +81 -0
- data/lib/enumerize/utils.rb +12 -0
- data/lib/enumerize/value.rb +47 -0
- data/lib/enumerize/version.rb +5 -0
- data/lib/enumerize.rb +90 -0
- data/lib/sequel/plugins/enumerize.rb +18 -0
- data/spec/enumerize/integrations/rspec/matcher_spec.rb +261 -0
- data/spec/spec_helper.rb +30 -0
- data/test/activemodel_test.rb +114 -0
- data/test/activerecord_test.rb +679 -0
- data/test/attribute_map_test.rb +70 -0
- data/test/attribute_test.rb +141 -0
- data/test/base_test.rb +230 -0
- data/test/formtastic_test.rb +152 -0
- data/test/module_attributes_test.rb +52 -0
- data/test/mongo_mapper_test.rb +83 -0
- data/test/mongoid_test.rb +164 -0
- data/test/multiple_test.rb +65 -0
- data/test/predicates_test.rb +65 -0
- data/test/rails_admin_test.rb +27 -0
- data/test/sequel_test.rb +344 -0
- data/test/set_test.rb +166 -0
- data/test/simple_form_test.rb +156 -0
- data/test/support/mock_controller.rb +31 -0
- data/test/support/shared_enums.rb +43 -0
- data/test/support/view_test_helper.rb +46 -0
- data/test/test_helper.rb +53 -0
- data/test/value_test.rb +158 -0
- metadata +143 -0
@@ -0,0 +1,142 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Enumerize
|
4
|
+
module ActiveRecordSupport
|
5
|
+
def enumerize(name, options={})
|
6
|
+
super
|
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
|
+
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
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
module InstanceMethods
|
43
|
+
# https://github.com/brainspec/enumerize/issues/74
|
44
|
+
def write_attribute(attr_name, value, *options)
|
45
|
+
if self.class.enumerized_attributes[attr_name]
|
46
|
+
_enumerized_values_for_validation[attr_name.to_s] = value
|
47
|
+
end
|
48
|
+
|
49
|
+
super
|
50
|
+
end
|
51
|
+
|
52
|
+
# Support multiple enumerized attributes
|
53
|
+
def becomes(klass)
|
54
|
+
became = super
|
55
|
+
klass.enumerized_attributes.each do |attr|
|
56
|
+
# Rescue when column associated to the enum does not exist.
|
57
|
+
begin
|
58
|
+
became.send("#{attr.name}=", send(attr.name))
|
59
|
+
rescue ActiveModel::MissingAttributeError
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
became
|
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
|
87
|
+
end
|
88
|
+
|
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
|
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
|
109
|
+
end
|
110
|
+
|
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, subtype: @subtype}.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
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,192 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Enumerize
|
4
|
+
class Attribute
|
5
|
+
attr_reader :klass, :name, :values, :default_value, :i18n_scope, :skip_validations_value
|
6
|
+
|
7
|
+
def initialize(klass, name, options={})
|
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]
|
12
|
+
|
13
|
+
@klass = klass
|
14
|
+
@name = name.to_sym
|
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
|
+
|
24
|
+
@value_hash = Hash[@values.map { |v| [v.value.to_s, v] }]
|
25
|
+
@value_hash.merge! Hash[@values.map { |v| [v.to_s, v] }]
|
26
|
+
|
27
|
+
if options[:default]
|
28
|
+
@default_value = find_default_value(options[:default])
|
29
|
+
raise ArgumentError, 'invalid default value' unless @default_value
|
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
|
41
|
+
end
|
42
|
+
|
43
|
+
def find_value(value)
|
44
|
+
@value_hash[value.to_s] unless value.nil?
|
45
|
+
end
|
46
|
+
|
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
|
151
|
+
end
|
152
|
+
|
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 = self.#{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
|
+
self.#{name}
|
188
|
+
end
|
189
|
+
RUBY
|
190
|
+
end
|
191
|
+
end
|
192
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Enumerize
|
4
|
+
class AttributeMap
|
5
|
+
attr_reader :attributes
|
6
|
+
|
7
|
+
def initialize
|
8
|
+
@attributes = {}
|
9
|
+
@dependants = []
|
10
|
+
end
|
11
|
+
|
12
|
+
def [](name)
|
13
|
+
@attributes[name.to_s]
|
14
|
+
end
|
15
|
+
|
16
|
+
def <<(attr)
|
17
|
+
@attributes[attr.name.to_s] = attr
|
18
|
+
@dependants.each do |dependant|
|
19
|
+
dependant << attr
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def each
|
24
|
+
@attributes.each_pair do |_name, attr|
|
25
|
+
yield attr
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def empty?
|
30
|
+
@attributes.empty?
|
31
|
+
end
|
32
|
+
|
33
|
+
def add_dependant(dependant)
|
34
|
+
@dependants << dependant
|
35
|
+
each do |attr|
|
36
|
+
dependant << attr
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Enumerize
|
4
|
+
module Base
|
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
|
13
|
+
|
14
|
+
module ClassMethods
|
15
|
+
def enumerize(name, options={})
|
16
|
+
attr = Attribute.new(self, name, options)
|
17
|
+
enumerized_attributes << attr
|
18
|
+
|
19
|
+
unless methods.include?(attr.name)
|
20
|
+
_enumerize_module._class_methods.module_eval <<-RUBY, __FILE__, __LINE__ + 1
|
21
|
+
def #{attr.name}
|
22
|
+
enumerized_attributes[:#{attr.name}]
|
23
|
+
end
|
24
|
+
RUBY
|
25
|
+
end
|
26
|
+
|
27
|
+
attr.define_methods!(_enumerize_module)
|
28
|
+
end
|
29
|
+
|
30
|
+
def enumerized_attributes
|
31
|
+
@enumerized_attributes ||= AttributeMap.new
|
32
|
+
end
|
33
|
+
|
34
|
+
module Hook
|
35
|
+
def inherited(subclass)
|
36
|
+
enumerized_attributes.add_dependant subclass.enumerized_attributes
|
37
|
+
super subclass
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def _enumerize_module
|
44
|
+
@_enumerize_module ||= begin
|
45
|
+
mod = Module.new
|
46
|
+
include mod
|
47
|
+
mod
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def initialize(*args, **kwargs)
|
53
|
+
super
|
54
|
+
_set_default_value_for_enumerized_attributes
|
55
|
+
end
|
56
|
+
|
57
|
+
def read_attribute_for_validation(key)
|
58
|
+
key = key.to_s
|
59
|
+
|
60
|
+
if _enumerized_values_for_validation.has_key?(key)
|
61
|
+
_enumerized_values_for_validation[key]
|
62
|
+
elsif defined?(super)
|
63
|
+
super
|
64
|
+
else
|
65
|
+
send(key)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def _enumerized_values_for_validation
|
72
|
+
@_enumerized_values_for_validation ||= {}
|
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
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/concern'
|
4
|
+
|
5
|
+
module Enumerize
|
6
|
+
module Hooks
|
7
|
+
module FormtasticFormBuilderExtension
|
8
|
+
|
9
|
+
def input(method, options={})
|
10
|
+
enumerized_object = convert_to_model(object)
|
11
|
+
klass = enumerized_object.class
|
12
|
+
|
13
|
+
if klass.respond_to?(:enumerized_attributes) && (attr = klass.enumerized_attributes[method])
|
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
|
19
|
+
end
|
20
|
+
|
21
|
+
super(method, options)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
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
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'active_support/concern'
|
4
|
+
|
5
|
+
module Enumerize
|
6
|
+
module Hooks
|
7
|
+
module SimpleFormBuilderExtension
|
8
|
+
|
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)
|
17
|
+
end
|
18
|
+
|
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
|
+
|
25
|
+
if klass.respond_to?(:enumerized_attributes) && (attr = klass.enumerized_attributes[attribute_name])
|
26
|
+
options[:collection] ||= attr.options
|
27
|
+
|
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
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
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
|