active_fields 0.1.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 (56) hide show
  1. checksums.yaml +7 -0
  2. data/.rspec +2 -0
  3. data/.rubocop.yml +60 -0
  4. data/CHANGELOG.md +5 -0
  5. data/CODE_OF_CONDUCT.md +84 -0
  6. data/LICENSE +21 -0
  7. data/README.md +5 -0
  8. data/Rakefile +3 -0
  9. data/lib/active_fields/casters/base_caster.rb +18 -0
  10. data/lib/active_fields/casters/boolean_caster.rb +23 -0
  11. data/lib/active_fields/casters/date_array_caster.rb +21 -0
  12. data/lib/active_fields/casters/date_caster.rb +25 -0
  13. data/lib/active_fields/casters/decimal_array_caster.rb +21 -0
  14. data/lib/active_fields/casters/decimal_caster.rb +23 -0
  15. data/lib/active_fields/casters/enum_array_caster.rb +9 -0
  16. data/lib/active_fields/casters/enum_caster.rb +9 -0
  17. data/lib/active_fields/casters/integer_array_caster.rb +21 -0
  18. data/lib/active_fields/casters/integer_caster.rb +23 -0
  19. data/lib/active_fields/casters/text_array_caster.rb +21 -0
  20. data/lib/active_fields/casters/text_caster.rb +23 -0
  21. data/lib/active_fields/models/concerns/concern.rb +16 -0
  22. data/lib/active_fields/models/concerns/customizable.rb +83 -0
  23. data/lib/active_fields/models/concerns/field_concern.rb +79 -0
  24. data/lib/active_fields/models/concerns/value_concern.rb +50 -0
  25. data/lib/active_fields/models/field/boolean.rb +38 -0
  26. data/lib/active_fields/models/field/date.rb +48 -0
  27. data/lib/active_fields/models/field/date_array.rb +44 -0
  28. data/lib/active_fields/models/field/decimal.rb +48 -0
  29. data/lib/active_fields/models/field/decimal_array.rb +44 -0
  30. data/lib/active_fields/models/field/enum.rb +62 -0
  31. data/lib/active_fields/models/field/enum_array.rb +59 -0
  32. data/lib/active_fields/models/field/integer.rb +48 -0
  33. data/lib/active_fields/models/field/integer_array.rb +34 -0
  34. data/lib/active_fields/models/field/text.rb +49 -0
  35. data/lib/active_fields/models/field/text_array.rb +35 -0
  36. data/lib/active_fields/models/field.rb +27 -0
  37. data/lib/active_fields/models/value.rb +30 -0
  38. data/lib/active_fields/validators/base_validator.rb +73 -0
  39. data/lib/active_fields/validators/boolean_validator.rb +23 -0
  40. data/lib/active_fields/validators/date_array_validator.rb +28 -0
  41. data/lib/active_fields/validators/date_validator.rb +21 -0
  42. data/lib/active_fields/validators/decimal_array_validator.rb +28 -0
  43. data/lib/active_fields/validators/decimal_validator.rb +21 -0
  44. data/lib/active_fields/validators/enum_array_validator.rb +36 -0
  45. data/lib/active_fields/validators/enum_validator.rb +25 -0
  46. data/lib/active_fields/validators/integer_array_validator.rb +28 -0
  47. data/lib/active_fields/validators/integer_validator.rb +21 -0
  48. data/lib/active_fields/validators/text_array_validator.rb +28 -0
  49. data/lib/active_fields/validators/text_validator.rb +21 -0
  50. data/lib/active_fields/version.rb +5 -0
  51. data/lib/active_fields.rb +13 -0
  52. data/lib/generators/active_fields/install/USAGE +5 -0
  53. data/lib/generators/active_fields/install/install_generator.rb +33 -0
  54. data/lib/generators/active_fields/install/templates/create_active_fields_tables.rb.tt +30 -0
  55. data/sig/active_fields.rbs +4 -0
  56. metadata +282 -0
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../field"
4
+
5
+ module ActiveFields
6
+ class Field
7
+ class Boolean < ActiveFields::Field
8
+ store_accessor :options, :required, :nullable
9
+
10
+ # attribute :required, :boolean, default: false
11
+ # attribute :nullable, :boolean, default: false
12
+
13
+ validates :required, exclusion: [nil]
14
+ validates :nullable, exclusion: [nil]
15
+
16
+ %i[required nullable].each do |column|
17
+ define_method(column) do
18
+ ActiveFields::Casters::BooleanCaster.new.deserialize(super())
19
+ end
20
+
21
+ define_method(:"#{column}?") do
22
+ !!public_send(column)
23
+ end
24
+
25
+ define_method(:"#{column}=") do |other|
26
+ super(ActiveFields::Casters::BooleanCaster.new.serialize(other))
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def set_defaults
33
+ self.required ||= false
34
+ self.nullable ||= false
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../field"
4
+
5
+ module ActiveFields
6
+ class Field
7
+ class Date < ActiveFields::Field
8
+ store_accessor :options, :required, :min, :max
9
+
10
+ # attribute :required, :boolean, default: false
11
+ # attribute :min, :date
12
+ # attribute :max, :date
13
+
14
+ validates :required, exclusion: [nil]
15
+ validates :max, comparison: { greater_than_or_equal_to: :min }, allow_nil: true, if: :min
16
+
17
+ %i[required].each do |column|
18
+ define_method(column) do
19
+ ActiveFields::Casters::BooleanCaster.new.deserialize(super())
20
+ end
21
+
22
+ define_method(:"#{column}?") do
23
+ !!public_send(column)
24
+ end
25
+
26
+ define_method(:"#{column}=") do |other|
27
+ super(ActiveFields::Casters::BooleanCaster.new.serialize(other))
28
+ end
29
+ end
30
+
31
+ %i[min max].each do |column|
32
+ define_method(column) do
33
+ ActiveFields::Casters::DateCaster.new.deserialize(super())
34
+ end
35
+
36
+ define_method(:"#{column}=") do |other|
37
+ super(ActiveFields::Casters::DateCaster.new.serialize(other))
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ def set_defaults
44
+ self.required ||= false
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../field"
4
+
5
+ module ActiveFields
6
+ class Field
7
+ class DateArray < ActiveFields::Field
8
+ store_accessor :options, :min_size, :max_size, :min, :max
9
+
10
+ # attribute :min_size, :integer
11
+ # attribute :max_size, :integer
12
+ # attribute :min, :date
13
+ # attribute :max, :date
14
+
15
+ validates :min_size, comparison: { greater_than_or_equal_to: 0 }, allow_nil: true
16
+ validates :max_size, comparison: { greater_than_or_equal_to: ->(r) { r.min_size || 0 } }, allow_nil: true
17
+ validates :max, comparison: { greater_than_or_equal_to: :min }, allow_nil: true, if: :min
18
+
19
+ %i[min_size max_size].each do |column|
20
+ define_method(column) do
21
+ ActiveFields::Casters::IntegerCaster.new.deserialize(super())
22
+ end
23
+
24
+ define_method(:"#{column}=") do |other|
25
+ super(ActiveFields::Casters::IntegerCaster.new.serialize(other))
26
+ end
27
+ end
28
+
29
+ %i[min max].each do |column|
30
+ define_method(column) do
31
+ ActiveFields::Casters::DateCaster.new.deserialize(super())
32
+ end
33
+
34
+ define_method(:"#{column}=") do |other|
35
+ super(ActiveFields::Casters::DateCaster.new.serialize(other))
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def set_defaults; end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../field"
4
+
5
+ module ActiveFields
6
+ class Field
7
+ class Decimal < ActiveFields::Field
8
+ store_accessor :options, :required, :min, :max
9
+
10
+ # attribute :required, :boolean, default: false
11
+ # attribute :min, :decimal
12
+ # attribute :max, :decimal
13
+
14
+ validates :required, exclusion: [nil]
15
+ validates :max, comparison: { greater_than_or_equal_to: :min }, allow_nil: true, if: :min
16
+
17
+ %i[required].each do |column|
18
+ define_method(column) do
19
+ ActiveFields::Casters::BooleanCaster.new.deserialize(super())
20
+ end
21
+
22
+ define_method(:"#{column}?") do
23
+ !!public_send(column)
24
+ end
25
+
26
+ define_method(:"#{column}=") do |other|
27
+ super(ActiveFields::Casters::BooleanCaster.new.serialize(other))
28
+ end
29
+ end
30
+
31
+ %i[min max].each do |column|
32
+ define_method(column) do
33
+ ActiveFields::Casters::DecimalCaster.new.deserialize(super())
34
+ end
35
+
36
+ define_method(:"#{column}=") do |other|
37
+ super(ActiveFields::Casters::DecimalCaster.new.serialize(other))
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ def set_defaults
44
+ self.required ||= false
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../field"
4
+
5
+ module ActiveFields
6
+ class Field
7
+ class DecimalArray < ActiveFields::Field
8
+ store_accessor :options, :min_size, :max_size, :min, :max
9
+
10
+ # attribute :min_size, :integer
11
+ # attribute :max_size, :integer
12
+ # attribute :min, :decimal
13
+ # attribute :max, :decimal
14
+
15
+ validates :min_size, comparison: { greater_than_or_equal_to: 0 }, allow_nil: true
16
+ validates :max_size, comparison: { greater_than_or_equal_to: ->(r) { r.min_size || 0 } }, allow_nil: true
17
+ validates :max, comparison: { greater_than_or_equal_to: :min }, allow_nil: true, if: :min
18
+
19
+ %i[min_size max_size].each do |column|
20
+ define_method(column) do
21
+ ActiveFields::Casters::IntegerCaster.new.deserialize(super())
22
+ end
23
+
24
+ define_method(:"#{column}=") do |other|
25
+ super(ActiveFields::Casters::IntegerCaster.new.serialize(other))
26
+ end
27
+ end
28
+
29
+ %i[min max].each do |column|
30
+ define_method(column) do
31
+ ActiveFields::Casters::DecimalCaster.new.deserialize(super())
32
+ end
33
+
34
+ define_method(:"#{column}=") do |other|
35
+ super(ActiveFields::Casters::DecimalCaster.new.serialize(other))
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ def set_defaults; end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../field"
4
+
5
+ module ActiveFields
6
+ class Field
7
+ class Enum < ActiveFields::Field
8
+ store_accessor :options, :required, :allowed_values
9
+
10
+ # attribute :required, :boolean, default: false
11
+ # attribute :allowed_values, :string, array: true, default: []
12
+
13
+ validates :required, exclusion: [nil]
14
+ validate :validate_allowed_values
15
+
16
+ %i[required].each do |column|
17
+ define_method(column) do
18
+ ActiveFields::Casters::BooleanCaster.new.deserialize(super())
19
+ end
20
+
21
+ define_method(:"#{column}?") do
22
+ !!public_send(column)
23
+ end
24
+
25
+ define_method(:"#{column}=") do |other|
26
+ super(ActiveFields::Casters::BooleanCaster.new.serialize(other))
27
+ end
28
+ end
29
+
30
+ %i[allowed_values].each do |column|
31
+ define_method(column) do
32
+ ActiveFields::Casters::TextArrayCaster.new.deserialize(super())
33
+ end
34
+
35
+ define_method(:"#{column}=") do |other|
36
+ super(ActiveFields::Casters::TextArrayCaster.new.serialize(other))
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ def validate_allowed_values
43
+ if allowed_values.nil?
44
+ errors.add(:allowed_values, :blank)
45
+ elsif allowed_values.is_a?(Array)
46
+ if allowed_values.empty?
47
+ errors.add(:allowed_values, :blank)
48
+ elsif allowed_values.any? { !_1.is_a?(String) }
49
+ errors.add(:allowed_values, :invalid)
50
+ end
51
+ else
52
+ errors.add(:allowed_values, :invalid)
53
+ end
54
+ end
55
+
56
+ def set_defaults
57
+ self.required ||= false
58
+ self.allowed_values ||= []
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../field"
4
+
5
+ module ActiveFields
6
+ class Field
7
+ class EnumArray < ActiveFields::Field
8
+ store_accessor :options, :min_size, :max_size, :allowed_values
9
+
10
+ # attribute :min_size, :integer
11
+ # attribute :max_size, :integer
12
+ # attribute :allowed_values, :string, array: true, default: []
13
+
14
+ validates :min_size, comparison: { greater_than_or_equal_to: 0 }, allow_nil: true
15
+ validates :max_size, comparison: { greater_than_or_equal_to: ->(r) { r.min_size || 0 } }, allow_nil: true
16
+ validate :validate_allowed_values
17
+
18
+ %i[min_size max_size].each do |column|
19
+ define_method(column) do
20
+ ActiveFields::Casters::IntegerCaster.new.deserialize(super())
21
+ end
22
+
23
+ define_method(:"#{column}=") do |other|
24
+ super(ActiveFields::Casters::IntegerCaster.new.serialize(other))
25
+ end
26
+ end
27
+
28
+ %i[allowed_values].each do |column|
29
+ define_method(column) do
30
+ ActiveFields::Casters::TextArrayCaster.new.deserialize(super())
31
+ end
32
+
33
+ define_method(:"#{column}=") do |other|
34
+ super(ActiveFields::Casters::TextArrayCaster.new.serialize(other))
35
+ end
36
+ end
37
+
38
+ private
39
+
40
+ def validate_allowed_values
41
+ if allowed_values.nil?
42
+ errors.add(:allowed_values, :blank)
43
+ elsif allowed_values.is_a?(Array)
44
+ if allowed_values.empty?
45
+ errors.add(:allowed_values, :blank)
46
+ elsif allowed_values.any? { !_1.is_a?(String) }
47
+ errors.add(:allowed_values, :invalid)
48
+ end
49
+ else
50
+ errors.add(:allowed_values, :invalid)
51
+ end
52
+ end
53
+
54
+ def set_defaults
55
+ self.allowed_values ||= []
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../field"
4
+
5
+ module ActiveFields
6
+ class Field
7
+ class Integer < ActiveFields::Field
8
+ store_accessor :options, :required, :min, :max
9
+
10
+ # attribute :required, :boolean, default: false
11
+ # attribute :min, :integer
12
+ # attribute :max, :integer
13
+
14
+ validates :required, exclusion: [nil]
15
+ validates :max, comparison: { greater_than_or_equal_to: :min }, allow_nil: true, if: :min
16
+
17
+ %i[required].each do |column|
18
+ define_method(column) do
19
+ ActiveFields::Casters::BooleanCaster.new.deserialize(super())
20
+ end
21
+
22
+ define_method(:"#{column}?") do
23
+ !!public_send(column)
24
+ end
25
+
26
+ define_method(:"#{column}=") do |other|
27
+ super(ActiveFields::Casters::BooleanCaster.new.serialize(other))
28
+ end
29
+ end
30
+
31
+ %i[min max].each do |column|
32
+ define_method(column) do
33
+ ActiveFields::Casters::IntegerCaster.new.deserialize(super())
34
+ end
35
+
36
+ define_method(:"#{column}=") do |other|
37
+ super(ActiveFields::Casters::IntegerCaster.new.serialize(other))
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ def set_defaults
44
+ self.required ||= false
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../field"
4
+
5
+ module ActiveFields
6
+ class Field
7
+ class IntegerArray < ActiveFields::Field
8
+ store_accessor :options, :min_size, :max_size, :min, :max
9
+
10
+ # attribute :min_size, :integer
11
+ # attribute :max_size, :integer
12
+ # attribute :min, :integer
13
+ # attribute :max, :integer
14
+
15
+ validates :min_size, comparison: { greater_than_or_equal_to: 0 }, allow_nil: true
16
+ validates :max_size, comparison: { greater_than_or_equal_to: ->(r) { r.min_size || 0 } }, allow_nil: true
17
+ validates :max, comparison: { greater_than_or_equal_to: :min }, allow_nil: true, if: :min
18
+
19
+ %i[min_size max_size min max].each do |column|
20
+ define_method(column) do
21
+ ActiveFields::Casters::IntegerCaster.new.deserialize(super())
22
+ end
23
+
24
+ define_method(:"#{column}=") do |other|
25
+ super(ActiveFields::Casters::IntegerCaster.new.serialize(other))
26
+ end
27
+ end
28
+
29
+ private
30
+
31
+ def set_defaults; end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,49 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../field"
4
+
5
+ module ActiveFields
6
+ class Field
7
+ class Text < ActiveFields::Field
8
+ store_accessor :options, :required, :min_length, :max_length
9
+
10
+ # attribute :required, :boolean, default: false
11
+ # attribute :min_length, :integer
12
+ # attribute :max_length, :integer
13
+
14
+ validates :required, exclusion: [nil]
15
+ validates :min_length, comparison: { greater_than_or_equal_to: 0 }, allow_nil: true
16
+ validates :max_length, comparison: { greater_than_or_equal_to: ->(r) { r.min_length || 0 } }, allow_nil: true
17
+
18
+ %i[required].each do |column|
19
+ define_method(column) do
20
+ ActiveFields::Casters::BooleanCaster.new.deserialize(super())
21
+ end
22
+
23
+ define_method(:"#{column}?") do
24
+ !!public_send(column)
25
+ end
26
+
27
+ define_method(:"#{column}=") do |other|
28
+ super(ActiveFields::Casters::BooleanCaster.new.serialize(other))
29
+ end
30
+ end
31
+
32
+ %i[min_length max_length].each do |column|
33
+ define_method(column) do
34
+ ActiveFields::Casters::IntegerCaster.new.deserialize(super())
35
+ end
36
+
37
+ define_method(:"#{column}=") do |other|
38
+ super(ActiveFields::Casters::IntegerCaster.new.serialize(other))
39
+ end
40
+ end
41
+
42
+ private
43
+
44
+ def set_defaults
45
+ self.required ||= false
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "../field"
4
+
5
+ module ActiveFields
6
+ class Field
7
+ class TextArray < ActiveFields::Field
8
+ store_accessor :options, :min_size, :max_size, :min_length, :max_length
9
+
10
+ # attribute :min_size, :integer
11
+ # attribute :max_size, :integer
12
+ # attribute :min_length, :integer
13
+ # attribute :max_length, :integer
14
+
15
+ validates :min_size, comparison: { greater_than_or_equal_to: 0 }, allow_nil: true
16
+ validates :max_size, comparison: { greater_than_or_equal_to: ->(r) { r.min_size || 0 } }, allow_nil: true
17
+ validates :min_length, comparison: { greater_than_or_equal_to: 0 }, allow_nil: true
18
+ validates :max_length, comparison: { greater_than_or_equal_to: ->(r) { r.min_length || 0 } }, allow_nil: true
19
+
20
+ %i[min_size max_size min_length max_length].each do |column|
21
+ define_method(column) do
22
+ ActiveFields::Casters::IntegerCaster.new.deserialize(super())
23
+ end
24
+
25
+ define_method(:"#{column}=") do |other|
26
+ super(ActiveFields::Casters::IntegerCaster.new.serialize(other))
27
+ end
28
+ end
29
+
30
+ private
31
+
32
+ def set_defaults; end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ # == Schema Information
4
+ #
5
+ # Table name: active_fields
6
+ #
7
+ # id :bigint not null, primary key
8
+ # customizable_type :string not null
9
+ # default_value :jsonb
10
+ # name :string not null
11
+ # options :jsonb default({}), not null
12
+ # type :string not null
13
+ # created_at :datetime not null
14
+ # updated_at :datetime not null
15
+ #
16
+ # Indexes
17
+ #
18
+ # index_active_fields_on_customizable_type (customizable_type)
19
+ # index_active_fields_on_name_and_customizable_type (name,customizable_type) UNIQUE
20
+ #
21
+ module ActiveFields
22
+ class Field < ::ActiveRecord::Base
23
+ self.table_name = "active_fields"
24
+
25
+ include ActiveFields::FieldConcern
26
+ end
27
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ # == Schema Information
4
+ #
5
+ # Table name: active_fields_values
6
+ #
7
+ # id :bigint not null, primary key
8
+ # customizable_type :string not null
9
+ # value :jsonb
10
+ # created_at :datetime not null
11
+ # updated_at :datetime not null
12
+ # customizable_id :bigint not null
13
+ # active_field_id :bigint not null
14
+ #
15
+ # Indexes
16
+ #
17
+ # index_active_fields_values_on_customizable_and_field (customizable_type,customizable_id,active_field_id) UNIQUE
18
+ # index_active_fields_values_on_active_field_id (active_field_id)
19
+ #
20
+ # Foreign Keys
21
+ #
22
+ # active_fields_values_active_field_id_fk (active_field_id => active_fields.id)
23
+ #
24
+ module ActiveFields
25
+ class Value < ::ActiveRecord::Base
26
+ self.table_name = "active_fields_values"
27
+
28
+ include ActiveFields::ValueConcern
29
+ end
30
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActiveFields
4
+ module Validators
5
+ # Validates the active_value value
6
+ class BaseValidator
7
+ attr_reader :active_field, :errors
8
+
9
+ def initialize(active_field)
10
+ @active_field = active_field
11
+ @errors = Set.new
12
+ end
13
+
14
+ def validate(value)
15
+ perform_validation(value)
16
+ valid?
17
+ end
18
+
19
+ def valid?
20
+ errors.empty?
21
+ end
22
+
23
+ private
24
+
25
+ def perform_validation(value)
26
+ raise NotImplementedError
27
+ end
28
+
29
+ def validate_size(value, min:, max:)
30
+ if min && value.size < min
31
+ errors << [:size_too_short, count: min]
32
+ end
33
+
34
+ if max && value.size > max
35
+ errors << [:size_too_long, count: max]
36
+ end
37
+ end
38
+
39
+ def validate_length(value, min:, max:)
40
+ if min && value.length < min
41
+ errors << [:too_short, count: min]
42
+ end
43
+
44
+ if max && value.length > max
45
+ errors << [:too_long, count: max]
46
+ end
47
+ end
48
+
49
+ def validate_minmax(value, min:, max:)
50
+ # maybe acts_like?(:date) || acts_like?(:time)
51
+ if min && value < min
52
+ formatted =
53
+ if min.respond_to?(:strftime) && defined?(I18n) && I18n.respond_to?(:l)
54
+ I18n.l(min)
55
+ else
56
+ min
57
+ end
58
+ errors << [:greater_than_or_equal_to, count: formatted]
59
+ end
60
+
61
+ if max && value > max
62
+ formatted =
63
+ if max.respond_to?(:strftime) && defined?(I18n) && I18n.respond_to?(:l)
64
+ I18n.l(max)
65
+ else
66
+ max
67
+ end
68
+ errors << [:less_than_or_equal_to, count: formatted]
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "base_validator"
4
+
5
+ module ActiveFields
6
+ module Validators
7
+ class BooleanValidator < BaseValidator
8
+ private
9
+
10
+ def perform_validation(value)
11
+ if value.nil?
12
+ errors << :exclusion unless active_field.nullable?
13
+ elsif value.is_a?(FalseClass)
14
+ errors << :required if active_field.required?
15
+ elsif value.is_a?(TrueClass)
16
+ nil
17
+ else
18
+ errors << :invalid
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end