phlexi-form 0.3.0.rc1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +10 -8
  3. data/gemfiles/default.gemfile.lock +34 -32
  4. data/gemfiles/rails_7.gemfile.lock +16 -18
  5. data/lib/phlexi/form/base.rb +42 -41
  6. data/lib/phlexi/form/builder.rb +297 -0
  7. data/lib/phlexi/form/components/base.rb +3 -3
  8. data/lib/phlexi/form/components/collection_checkboxes.rb +1 -1
  9. data/lib/phlexi/form/components/collection_radio_buttons.rb +1 -1
  10. data/lib/phlexi/form/components/concerns/extracts_input.rb +53 -0
  11. data/lib/phlexi/form/components/concerns/handles_input.rb +4 -34
  12. data/lib/phlexi/form/components/concerns/submits_form.rb +8 -0
  13. data/lib/phlexi/form/components/error.rb +1 -1
  14. data/lib/phlexi/form/components/file_input.rb +1 -0
  15. data/lib/phlexi/form/components/hint.rb +1 -1
  16. data/lib/phlexi/form/components/input.rb +16 -6
  17. data/lib/phlexi/form/components/input_array.rb +1 -1
  18. data/lib/phlexi/form/components/select.rb +4 -3
  19. data/lib/phlexi/form/components/textarea.rb +2 -3
  20. data/lib/phlexi/form/html.rb +18 -0
  21. data/lib/phlexi/form/{field_options → options}/autofocus.rb +1 -1
  22. data/lib/phlexi/form/{field_options → options}/collection.rb +14 -10
  23. data/lib/phlexi/form/{field_options → options}/disabled.rb +1 -1
  24. data/lib/phlexi/form/{field_options → options}/errors.rb +18 -14
  25. data/lib/phlexi/form/options/hints.rb +13 -0
  26. data/lib/phlexi/form/options/inferred_types.rb +32 -0
  27. data/lib/phlexi/form/{field_options → options}/length.rb +3 -3
  28. data/lib/phlexi/form/{field_options → options}/limit.rb +2 -2
  29. data/lib/phlexi/form/options/max.rb +55 -0
  30. data/lib/phlexi/form/options/min.rb +55 -0
  31. data/lib/phlexi/form/{field_options → options}/pattern.rb +2 -2
  32. data/lib/phlexi/form/{field_options → options}/readonly.rb +1 -1
  33. data/lib/phlexi/form/{field_options → options}/required.rb +3 -3
  34. data/lib/phlexi/form/options/step.rb +39 -0
  35. data/lib/phlexi/form/options/validators.rb +24 -0
  36. data/lib/phlexi/form/structure/field_collection.rb +12 -27
  37. data/lib/phlexi/form/structure/namespace.rb +4 -111
  38. data/lib/phlexi/form/structure/namespace_collection.rb +1 -32
  39. data/lib/phlexi/form/theme.rb +160 -0
  40. data/lib/phlexi/form/version.rb +1 -1
  41. data/lib/phlexi/form.rb +3 -6
  42. metadata +36 -24
  43. data/lib/phlexi/form/field_options/associations.rb +0 -21
  44. data/lib/phlexi/form/field_options/hints.rb +0 -22
  45. data/lib/phlexi/form/field_options/inferred_types.rb +0 -155
  46. data/lib/phlexi/form/field_options/labels.rb +0 -28
  47. data/lib/phlexi/form/field_options/min_max.rb +0 -92
  48. data/lib/phlexi/form/field_options/multiple.rb +0 -65
  49. data/lib/phlexi/form/field_options/placeholder.rb +0 -18
  50. data/lib/phlexi/form/field_options/themes.rb +0 -207
  51. data/lib/phlexi/form/field_options/validators.rb +0 -48
  52. data/lib/phlexi/form/structure/dom.rb +0 -62
  53. data/lib/phlexi/form/structure/field_builder.rb +0 -236
  54. data/lib/phlexi/form/structure/node.rb +0 -18
@@ -0,0 +1,160 @@
1
+ module Phlexi
2
+ module Form
3
+ class Theme < Phlexi::Field::Theme
4
+ def self.theme
5
+ @theme ||= {
6
+ # == Base
7
+ base: nil,
8
+ hint: nil,
9
+ error: nil,
10
+ full_error: :error,
11
+ wrapper: nil,
12
+ inner_wrapper: nil,
13
+ button: nil,
14
+ submit_button: :button,
15
+
16
+ # == Label
17
+ label: nil,
18
+ invalid_label: nil,
19
+ valid_label: nil,
20
+ neutral_label: nil,
21
+
22
+ # == Input
23
+ input: nil,
24
+ valid_input: nil,
25
+ invalid_input: nil,
26
+ neutral_input: nil,
27
+
28
+ # String
29
+ string: :input,
30
+ valid_string: :valid_input,
31
+ invalid_string: :invalid_input,
32
+ neutral_string: :neutral_input,
33
+
34
+ # Email
35
+ email: :input,
36
+ valid_email: :valid_input,
37
+ invalid_email: :invalid_input,
38
+ neutral_email: :neutral_input,
39
+
40
+ # Password
41
+ password: :input,
42
+ valid_password: :valid_input,
43
+ invalid_password: :invalid_input,
44
+ neutral_password: :neutral_input,
45
+
46
+ # Phone
47
+ phone: :input,
48
+ valid_phone: :valid_input,
49
+ invalid_phone: :invalid_input,
50
+ neutral_phone: :neutral_input,
51
+
52
+ # Color
53
+ color: :input,
54
+ valid_color: :valid_input,
55
+ invalid_color: :invalid_input,
56
+ neutral_color: :neutral_input,
57
+
58
+ # Url
59
+ url: :input,
60
+ valid_url: :valid_input,
61
+ invalid_url: :invalid_input,
62
+ neutral_url: :neutral_input,
63
+
64
+ # Search
65
+ search: :input,
66
+ valid_search: :valid_input,
67
+ invalid_search: :invalid_input,
68
+ neutral_search: :neutral_input,
69
+
70
+ # Number
71
+ number: :input,
72
+ valid_number: :valid_input,
73
+ invalid_number: :invalid_input,
74
+ neutral_number: :neutral_input,
75
+
76
+ # Date
77
+ date: :input,
78
+ valid_date: :valid_input,
79
+ invalid_date: :invalid_input,
80
+ neutral_date: :neutral_input,
81
+
82
+ # Time
83
+ time: :input,
84
+ valid_time: :valid_input,
85
+ invalid_time: :invalid_input,
86
+ neutral_time: :neutral_input,
87
+
88
+ # DateTime
89
+ datetime: :input,
90
+ valid_datetime: :valid_input,
91
+ invalid_datetime: :invalid_input,
92
+ neutral_datetime: :neutral_input,
93
+
94
+ # Checkbox
95
+ checkbox: :input,
96
+ valid_checkbox: :valid_input,
97
+ invalid_checkbox: :invalid_input,
98
+ neutral_checkbox: :neutral_input,
99
+
100
+ # Boolean
101
+ boolan: :checkbox,
102
+ valid_boolan: :valid_checkbox,
103
+ invalid_boolan: :invalid_checkbox,
104
+ neutral_boolan: :neutral_checkbox,
105
+
106
+ # Textarea
107
+ textarea: :input,
108
+ valid_textarea: :valid_input,
109
+ invalid_textarea: :invalid_input,
110
+ neutral_textarea: :neutral_input,
111
+
112
+ # Hstore
113
+ hstore: :textarea,
114
+ valid_hstore: :valid_textarea,
115
+ invalid_hstore: :invalid_textarea,
116
+ neutral_hstore: :neutral_textarea,
117
+
118
+ # Select
119
+ select: :input,
120
+ valid_select: :valid_input,
121
+ invalid_select: :invalid_input,
122
+ neutral_select: :neutral_input,
123
+
124
+ # File
125
+ file: :input,
126
+ valid_file: :valid_input,
127
+ invalid_file: :invalid_input,
128
+ neutral_file: :neutral_input
129
+
130
+ }.freeze
131
+ end
132
+
133
+ # Resolves the theme for a component based on its current validity state
134
+ #
135
+ # This method determines the validity state of the field (valid, invalid, or neutral)
136
+ # and returns the corresponding theme by prepending the state to the component name.
137
+ #
138
+ # @param property [Symbol, String] The base theme property to resolve
139
+ # @return [String, nil] The resolved validity-specific theme or nil if not found
140
+ #
141
+ # @example Resolving a validity theme
142
+ # # Assuming the field has errors and the theme includes { invalid_input: "error-class" }
143
+ # resolve_validity_theme(:input)
144
+ # # => "error-class"
145
+ def resolve_validity_theme(property, field)
146
+ return unless field
147
+
148
+ validity_property = if field.has_errors?
149
+ :"invalid_#{property}"
150
+ elsif field.object_valid?
151
+ :"valid_#{property}"
152
+ else
153
+ :"neutral_#{property}"
154
+ end
155
+
156
+ resolve_theme(validity_property)
157
+ end
158
+ end
159
+ end
160
+ end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Phlexi
4
4
  module Form
5
- VERSION = "0.3.0.rc1"
5
+ VERSION = "0.4.0"
6
6
  end
7
7
  end
data/lib/phlexi/form.rb CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require "zeitwerk"
4
4
  require "phlex"
5
+ require "phlexi-field"
5
6
  require "active_support/core_ext/object/blank"
6
7
 
7
8
  module Phlexi
@@ -11,21 +12,17 @@ module Phlexi
11
12
  loader.inflector.inflect(
12
13
  "phlexi-form" => "Phlexi",
13
14
  "phlexi" => "Phlexi",
14
- "dom" => "DOM"
15
+ "html" => "HTML"
15
16
  )
16
17
  loader.push_dir(File.expand_path("..", __dir__))
17
18
  loader.ignore(File.expand_path("../generators", __dir__))
18
19
  loader.setup
19
20
  end
20
21
 
21
- COMPONENT_BASE = (defined?(::ApplicationComponent) ? ::ApplicationComponent : Phlex::HTML)
22
-
23
- NIL_VALUE = :__i_phlexi_form_nil_value_i__
24
-
25
22
  class Error < StandardError; end
26
23
  end
27
24
  end
28
25
 
29
26
  def Phlexi.Form(...)
30
- Phlexi::Form::Base.new(...)
27
+ Phlexi::Form::Base.inline(...)
31
28
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: phlexi-form
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0.rc1
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stefan Froelich
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-08-08 00:00:00.000000000 Z
11
+ date: 2024-09-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: phlex
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.11'
27
+ - !ruby/object:Gem::Dependency
28
+ name: phlexi-field
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: activesupport
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -190,10 +204,12 @@ files:
190
204
  - lib/phlexi-form.rb
191
205
  - lib/phlexi/form.rb
192
206
  - lib/phlexi/form/base.rb
207
+ - lib/phlexi/form/builder.rb
193
208
  - lib/phlexi/form/components/base.rb
194
209
  - lib/phlexi/form/components/checkbox.rb
195
210
  - lib/phlexi/form/components/collection_checkboxes.rb
196
211
  - lib/phlexi/form/components/collection_radio_buttons.rb
212
+ - lib/phlexi/form/components/concerns/extracts_input.rb
197
213
  - lib/phlexi/form/components/concerns/handles_array_input.rb
198
214
  - lib/phlexi/form/components/concerns/handles_input.rb
199
215
  - lib/phlexi/form/components/concerns/has_options.rb
@@ -210,31 +226,27 @@ files:
210
226
  - lib/phlexi/form/components/submit_button.rb
211
227
  - lib/phlexi/form/components/textarea.rb
212
228
  - lib/phlexi/form/components/wrapper.rb
213
- - lib/phlexi/form/field_options/associations.rb
214
- - lib/phlexi/form/field_options/autofocus.rb
215
- - lib/phlexi/form/field_options/collection.rb
216
- - lib/phlexi/form/field_options/disabled.rb
217
- - lib/phlexi/form/field_options/errors.rb
218
- - lib/phlexi/form/field_options/hints.rb
219
- - lib/phlexi/form/field_options/inferred_types.rb
220
- - lib/phlexi/form/field_options/labels.rb
221
- - lib/phlexi/form/field_options/length.rb
222
- - lib/phlexi/form/field_options/limit.rb
223
- - lib/phlexi/form/field_options/min_max.rb
224
- - lib/phlexi/form/field_options/multiple.rb
225
- - lib/phlexi/form/field_options/pattern.rb
226
- - lib/phlexi/form/field_options/placeholder.rb
227
- - lib/phlexi/form/field_options/readonly.rb
228
- - lib/phlexi/form/field_options/required.rb
229
- - lib/phlexi/form/field_options/themes.rb
230
- - lib/phlexi/form/field_options/validators.rb
229
+ - lib/phlexi/form/html.rb
231
230
  - lib/phlexi/form/option_mapper.rb
232
- - lib/phlexi/form/structure/dom.rb
233
- - lib/phlexi/form/structure/field_builder.rb
231
+ - lib/phlexi/form/options/autofocus.rb
232
+ - lib/phlexi/form/options/collection.rb
233
+ - lib/phlexi/form/options/disabled.rb
234
+ - lib/phlexi/form/options/errors.rb
235
+ - lib/phlexi/form/options/hints.rb
236
+ - lib/phlexi/form/options/inferred_types.rb
237
+ - lib/phlexi/form/options/length.rb
238
+ - lib/phlexi/form/options/limit.rb
239
+ - lib/phlexi/form/options/max.rb
240
+ - lib/phlexi/form/options/min.rb
241
+ - lib/phlexi/form/options/pattern.rb
242
+ - lib/phlexi/form/options/readonly.rb
243
+ - lib/phlexi/form/options/required.rb
244
+ - lib/phlexi/form/options/step.rb
245
+ - lib/phlexi/form/options/validators.rb
234
246
  - lib/phlexi/form/structure/field_collection.rb
235
247
  - lib/phlexi/form/structure/namespace.rb
236
248
  - lib/phlexi/form/structure/namespace_collection.rb
237
- - lib/phlexi/form/structure/node.rb
249
+ - lib/phlexi/form/theme.rb
238
250
  - lib/phlexi/form/version.rb
239
251
  - sig/phlexi/form.rbs
240
252
  homepage: https://github.com/radioactive-labs/phlexi-form
@@ -260,7 +272,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
260
272
  - !ruby/object:Gem::Version
261
273
  version: '0'
262
274
  requirements: []
263
- rubygems_version: 3.5.11
275
+ rubygems_version: 3.4.10
264
276
  signing_key:
265
277
  specification_version: 4
266
278
  summary: Build forms in Rails
@@ -1,21 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phlexi
4
- module Form
5
- module FieldOptions
6
- module Associations
7
- protected
8
-
9
- def reflection
10
- @reflection ||= find_association_reflection
11
- end
12
-
13
- def find_association_reflection
14
- if object.class.respond_to?(:reflect_on_association)
15
- object.class.reflect_on_association(key)
16
- end
17
- end
18
- end
19
- end
20
- end
21
- end
@@ -1,22 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phlexi
4
- module Form
5
- module FieldOptions
6
- module Hints
7
- def hint(hint = nil)
8
- if hint.nil?
9
- options[:hint]
10
- else
11
- options[:hint] = hint
12
- self
13
- end
14
- end
15
-
16
- def has_hint?
17
- options[:hint] != false && hint.present?
18
- end
19
- end
20
- end
21
- end
22
- end
@@ -1,155 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require "bigdecimal"
4
-
5
- module Phlexi
6
- module Form
7
- module FieldOptions
8
- module InferredTypes
9
- def inferred_db_type
10
- @inferred_db_type ||= infer_db_type
11
- end
12
-
13
- def inferred_input_component
14
- @inferred_input_component ||= infer_input_component
15
- end
16
-
17
- def inferred_input_type
18
- @inferred_input_type ||= infer_input_type(inferred_input_component)
19
- end
20
-
21
- private
22
-
23
- # this returns the element type
24
- # one of :input, :textarea, :select, :botton
25
- def infer_input_component
26
- return :select unless collection.blank?
27
-
28
- case inferred_db_type
29
- when :text, :json, :jsonb, :hstore
30
- :textarea
31
- else
32
- :input
33
- end
34
- end
35
-
36
- # this only applies when input_component is `:input`
37
- # resolves the type attribute of input components
38
- def infer_input_type(component)
39
- case inferred_db_type
40
- when :string
41
- infer_string_input_type(key)
42
- when :integer, :float, :decimal
43
- :number
44
- when :date
45
- :date
46
- when :datetime
47
- :datetime
48
- when :time
49
- :time
50
- when :boolean
51
- :checkbox
52
- else
53
- :text
54
- end
55
- end
56
-
57
- def infer_db_type
58
- if object.class.respond_to?(:columns_hash)
59
- # ActiveRecord object
60
- column = object.class.columns_hash[key.to_s]
61
- return column.type if column
62
- end
63
-
64
- if object.class.respond_to?(:attribute_types)
65
- # ActiveModel::Attributes
66
- custom_type = object.class.attribute_types[key.to_s]
67
- return custom_type.type if custom_type
68
- end
69
-
70
- # Check if object responds to the key
71
- if object.respond_to?(key)
72
- # Fallback to inferring type from the value
73
- return infer_db_type_from_value(object.send(key))
74
- end
75
-
76
- # Default to string if we can't determine the type
77
- :string
78
- end
79
-
80
- def infer_db_type_from_value(value)
81
- case value
82
- when Integer
83
- :integer
84
- when Float, BigDecimal
85
- :float
86
- when TrueClass, FalseClass
87
- :boolean
88
- when Date
89
- :date
90
- when Time, DateTime
91
- :datetime
92
- else
93
- :string
94
- end
95
- end
96
-
97
- def infer_string_input_type(key)
98
- key = key.to_s.downcase
99
-
100
- return :password if is_password_field?
101
-
102
- custom_type = custom_string_input_type(key)
103
- return custom_type if custom_type
104
-
105
- if has_validators?
106
- infer_string_input_type_from_validations
107
- else
108
- :text
109
- end
110
- end
111
-
112
- def custom_string_input_type(key)
113
- custom_mappings = {
114
- /url$|^link|^site/ => :url,
115
- /^email/ => :email,
116
- /^search/ => :search,
117
- /phone|tel(ephone)?/ => :tel,
118
- /^time/ => :time,
119
- /^date/ => :date,
120
- /^number|_count$|_amount$/ => :number,
121
- /^color/ => :color
122
- }
123
-
124
- custom_mappings.each do |pattern, type|
125
- return type if key.match?(pattern)
126
- end
127
-
128
- nil
129
- end
130
-
131
- def infer_string_input_type_from_validations
132
- if attribute_validators.find { |v| v.kind == :numericality }
133
- :number
134
- elsif attribute_validators.find { |v| v.kind == :format && v.options[:with] == URI::MailTo::EMAIL_REGEXP }
135
- :email
136
- else
137
- :text
138
- end
139
- end
140
-
141
- def is_password_field?
142
- key = self.key.to_s.downcase
143
-
144
- exact_matches = ["password"]
145
- prefixes = ["encrypted_"]
146
- suffixes = ["_password", "_digest", "_hash"]
147
-
148
- exact_matches.include?(key) ||
149
- prefixes.any? { |prefix| key.start_with?(prefix) } ||
150
- suffixes.any? { |suffix| key.end_with?(suffix) }
151
- end
152
- end
153
- end
154
- end
155
- end
@@ -1,28 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phlexi
4
- module Form
5
- module FieldOptions
6
- module Labels
7
- def label(label = nil)
8
- if label.nil?
9
- options[:label] = options.fetch(:label) { calculate_label }
10
- else
11
- options[:label] = label
12
- self
13
- end
14
- end
15
-
16
- private
17
-
18
- def calculate_label
19
- if object.class.respond_to?(:human_attribute_name)
20
- object.class.human_attribute_name(key.to_s, {base: object})
21
- else
22
- key.to_s.humanize
23
- end
24
- end
25
- end
26
- end
27
- end
28
- end
@@ -1,92 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phlexi
4
- module Form
5
- module FieldOptions
6
- module MinMax
7
- def min(min_value = nil)
8
- if min_value.nil?
9
- options[:min] = options.fetch(:min) { calculate_min }
10
- else
11
- options[:min] = min_value
12
- self
13
- end
14
- end
15
-
16
- def max(max_value = nil)
17
- if max_value.nil?
18
- options[:max] = options.fetch(:max) { calculate_max }
19
- else
20
- options[:max] = max_value
21
- self
22
- end
23
- end
24
-
25
- def step
26
- 1 if min || max
27
- end
28
-
29
- private
30
-
31
- def calculate_min
32
- if (numericality_validator = find_numericality_validator)
33
- get_min_from_validator(numericality_validator)
34
- end
35
- end
36
-
37
- def calculate_max
38
- if (numericality_validator = find_numericality_validator)
39
- get_max_from_validator(numericality_validator)
40
- end
41
- end
42
-
43
- def find_numericality_validator
44
- find_validator(:numericality)
45
- end
46
-
47
- def get_min_from_validator(validator)
48
- options = validator.options
49
- min = if options.key?(:greater_than)
50
- {value: options[:greater_than], exclusive: true}
51
- elsif options.key?(:greater_than_or_equal_to)
52
- {value: options[:greater_than_or_equal_to], exclusive: false}
53
- end
54
- evaluate_and_adjust_min(min)
55
- end
56
-
57
- def get_max_from_validator(validator)
58
- options = validator.options
59
- max = if options.key?(:less_than)
60
- {value: options[:less_than], exclusive: true}
61
- elsif options.key?(:less_than_or_equal_to)
62
- {value: options[:less_than_or_equal_to], exclusive: false}
63
- end
64
- evaluate_and_adjust_max(max)
65
- end
66
-
67
- def evaluate_and_adjust_min(min)
68
- return nil unless min
69
-
70
- value = evaluate_numericality_validator_option(min[:value])
71
- min[:exclusive] ? value + 1 : value
72
- end
73
-
74
- def evaluate_and_adjust_max(max)
75
- return nil unless max
76
-
77
- value = evaluate_numericality_validator_option(max[:value])
78
- max[:exclusive] ? value - 1 : value
79
- end
80
-
81
- def evaluate_numericality_validator_option(option)
82
- case option
83
- when Proc
84
- option.arity.zero? ? option.call : option.call(object)
85
- else
86
- option
87
- end
88
- end
89
- end
90
- end
91
- end
92
- end
@@ -1,65 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Phlexi
4
- module Form
5
- module FieldOptions
6
- module Multiple
7
- def multiple?
8
- options[:multiple] = options.fetch(:multiple) { calculate_multiple_field_value }
9
- end
10
-
11
- def multiple!(multiple = true)
12
- options[:multiple] = multiple
13
- self
14
- end
15
-
16
- private
17
-
18
- def calculate_multiple_field_value
19
- return true if reflection&.macro == :has_many
20
- return true if multiple_field_array_attribute?
21
-
22
- check_multiple_field_from_validators
23
- end
24
-
25
- def multiple_field_array_attribute?
26
- return false unless object.class.respond_to?(:columns_hash)
27
-
28
- column = object.class.columns_hash[key.to_s]
29
- return false unless column
30
-
31
- case object.class.connection.adapter_name.downcase
32
- when "postgresql"
33
- column.array? || (column.type == :string && column.sql_type.include?("[]"))
34
- end # || object.class.attribute_types[key.to_s].is_a?(ActiveRecord::Type::Serialized)
35
- rescue
36
- # Rails.logger.warn("Error checking multiple field array attribute: #{e.message}")
37
- false
38
- end
39
-
40
- def check_multiple_field_from_validators
41
- inclusion_validator = find_validator(:inclusion)
42
- length_validator = find_validator(:length)
43
-
44
- return false unless inclusion_validator || length_validator
45
-
46
- check_multiple_field_inclusion_validator(inclusion_validator) ||
47
- check_multiple_field_length_validator(length_validator)
48
- end
49
-
50
- def check_multiple_field_inclusion_validator(validator)
51
- return false unless validator
52
- in_option = validator.options[:in]
53
- return false unless in_option.is_a?(Array)
54
-
55
- validator.options[:multiple] == true || (multiple_field_array_attribute? && in_option.size > 1)
56
- end
57
-
58
- def check_multiple_field_length_validator(validator)
59
- return false unless validator
60
- validator.options[:maximum].to_i > 1 if validator.options[:maximum]
61
- end
62
- end
63
- end
64
- end
65
- end