granite-form 0.1.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (133) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -2
  3. data/.github/workflows/{ci.yml → ruby.yml} +22 -4
  4. data/.rubocop.yml +1 -1
  5. data/.rubocop_todo.yml +3 -3
  6. data/Appraisals +1 -2
  7. data/CHANGELOG.md +14 -0
  8. data/README.md +0 -2
  9. data/Rakefile +4 -0
  10. data/docker-compose.yml +14 -0
  11. data/gemfiles/rails.5.0.gemfile +0 -1
  12. data/gemfiles/rails.5.1.gemfile +0 -1
  13. data/gemfiles/rails.5.2.gemfile +0 -1
  14. data/granite-form.gemspec +16 -15
  15. data/lib/granite/form/active_record/associations.rb +1 -1
  16. data/lib/granite/form/base.rb +1 -2
  17. data/lib/granite/form/config.rb +10 -10
  18. data/lib/granite/form/errors.rb +0 -15
  19. data/lib/granite/form/model/associations/base.rb +0 -4
  20. data/lib/granite/form/model/associations/collection/embedded.rb +2 -1
  21. data/lib/granite/form/model/associations/collection/proxy.rb +1 -1
  22. data/lib/granite/form/model/associations/embeds_any.rb +7 -0
  23. data/lib/granite/form/model/associations/embeds_many.rb +9 -58
  24. data/lib/granite/form/model/associations/embeds_one.rb +7 -36
  25. data/lib/granite/form/model/associations/nested_attributes.rb +8 -8
  26. data/lib/granite/form/model/associations/persistence_adapters/active_record.rb +0 -4
  27. data/lib/granite/form/model/associations/persistence_adapters/base.rb +0 -4
  28. data/lib/granite/form/model/associations/references_many.rb +0 -32
  29. data/lib/granite/form/model/associations/references_one.rb +0 -28
  30. data/lib/granite/form/model/associations/reflections/embeds_any.rb +1 -1
  31. data/lib/granite/form/model/associations/reflections/references_any.rb +0 -4
  32. data/lib/granite/form/model/associations/reflections/references_many.rb +3 -1
  33. data/lib/granite/form/model/associations/reflections/references_one.rb +3 -3
  34. data/lib/granite/form/model/associations/reflections/singular.rb +0 -8
  35. data/lib/granite/form/model/associations.rb +0 -6
  36. data/lib/granite/form/model/attributes/attribute.rb +1 -1
  37. data/lib/granite/form/model/attributes/base.rb +14 -17
  38. data/lib/granite/form/model/attributes/collection.rb +1 -1
  39. data/lib/granite/form/model/attributes/dictionary.rb +1 -1
  40. data/lib/granite/form/model/attributes/localized.rb +1 -1
  41. data/lib/granite/form/model/attributes/reference_many.rb +1 -1
  42. data/lib/granite/form/model/attributes/reference_one.rb +1 -9
  43. data/lib/granite/form/model/attributes/reflections/attribute.rb +0 -6
  44. data/lib/granite/form/model/attributes/reflections/base.rb +9 -12
  45. data/lib/granite/form/model/attributes/reflections/reference_one.rb +0 -10
  46. data/lib/granite/form/model/persistence.rb +1 -19
  47. data/lib/granite/form/model/validations/nested.rb +1 -1
  48. data/lib/granite/form/model.rb +0 -2
  49. data/lib/granite/form/types/active_support/time_zone.rb +22 -0
  50. data/lib/granite/form/types/array.rb +17 -0
  51. data/lib/granite/form/types/big_decimal.rb +15 -0
  52. data/lib/granite/form/types/boolean.rb +38 -0
  53. data/lib/granite/form/types/date.rb +15 -0
  54. data/lib/granite/form/types/date_time.rb +15 -0
  55. data/lib/granite/form/types/float.rb +15 -0
  56. data/lib/granite/form/types/hash_with_action_controller_parameters.rb +18 -0
  57. data/lib/granite/form/types/integer.rb +13 -0
  58. data/lib/granite/form/types/object.rb +30 -0
  59. data/lib/granite/form/types/string.rb +13 -0
  60. data/lib/granite/form/types/time.rb +15 -0
  61. data/lib/granite/form/types/uuid.rb +22 -0
  62. data/lib/granite/form/types.rb +15 -0
  63. data/lib/granite/form/version.rb +1 -1
  64. data/lib/granite/form.rb +19 -118
  65. data/spec/{lib/granite → granite}/form/active_record/associations_spec.rb +16 -18
  66. data/spec/{lib/granite → granite}/form/active_record/nested_attributes_spec.rb +0 -1
  67. data/spec/{lib/granite → granite}/form/config_spec.rb +22 -10
  68. data/spec/granite/form/extensions_spec.rb +12 -0
  69. data/spec/{lib/granite → granite}/form/model/associations/embeds_many_spec.rb +29 -305
  70. data/spec/{lib/granite → granite}/form/model/associations/embeds_one_spec.rb +27 -212
  71. data/spec/granite/form/model/associations/nested_attributes_spec.rb +23 -0
  72. data/spec/{lib/granite → granite}/form/model/associations/persistence_adapters/active_record_spec.rb +0 -0
  73. data/spec/granite/form/model/associations/references_many_spec.rb +251 -0
  74. data/spec/granite/form/model/associations/references_one_spec.rb +173 -0
  75. data/spec/{lib/granite → granite}/form/model/associations/reflections/embeds_any_spec.rb +1 -2
  76. data/spec/{lib/granite → granite}/form/model/associations/reflections/embeds_many_spec.rb +18 -26
  77. data/spec/{lib/granite → granite}/form/model/associations/reflections/embeds_one_spec.rb +16 -23
  78. data/spec/{lib/granite → granite}/form/model/associations/reflections/references_many_spec.rb +1 -1
  79. data/spec/{lib/granite → granite}/form/model/associations/reflections/references_one_spec.rb +1 -22
  80. data/spec/{lib/granite → granite}/form/model/associations/validations_spec.rb +0 -3
  81. data/spec/{lib/granite → granite}/form/model/associations_spec.rb +3 -24
  82. data/spec/{lib/granite → granite}/form/model/attributes/attribute_spec.rb +4 -46
  83. data/spec/{lib/granite → granite}/form/model/attributes/base_spec.rb +11 -2
  84. data/spec/{lib/granite → granite}/form/model/attributes/collection_spec.rb +0 -0
  85. data/spec/{lib/granite → granite}/form/model/attributes/dictionary_spec.rb +0 -0
  86. data/spec/{lib/granite → granite}/form/model/attributes/localized_spec.rb +1 -1
  87. data/spec/{lib/granite → granite}/form/model/attributes/reflections/attribute_spec.rb +0 -12
  88. data/spec/{lib/granite → granite}/form/model/attributes/reflections/base_spec.rb +1 -1
  89. data/spec/{lib/granite → granite}/form/model/attributes/reflections/collection_spec.rb +0 -0
  90. data/spec/{lib/granite → granite}/form/model/attributes/reflections/dictionary_spec.rb +0 -0
  91. data/spec/{lib/granite → granite}/form/model/attributes/reflections/localized_spec.rb +0 -0
  92. data/spec/{lib/granite → granite}/form/model/attributes/reflections/represents_spec.rb +0 -0
  93. data/spec/{lib/granite → granite}/form/model/attributes/represents_spec.rb +0 -0
  94. data/spec/{lib/granite → granite}/form/model/attributes_spec.rb +0 -0
  95. data/spec/{lib/granite → granite}/form/model/conventions_spec.rb +0 -0
  96. data/spec/{lib/granite → granite}/form/model/dirty_spec.rb +1 -1
  97. data/spec/{lib/granite → granite}/form/model/persistence_spec.rb +0 -2
  98. data/spec/{lib/granite → granite}/form/model/primary_spec.rb +1 -1
  99. data/spec/{lib/granite → granite}/form/model/representation_spec.rb +0 -0
  100. data/spec/{lib/granite → granite}/form/model/scopes_spec.rb +0 -0
  101. data/spec/{lib/granite → granite}/form/model/validations/associated_spec.rb +2 -4
  102. data/spec/{lib/granite → granite}/form/model/validations/nested_spec.rb +57 -15
  103. data/spec/{lib/granite → granite}/form/model/validations_spec.rb +0 -0
  104. data/spec/{lib/granite → granite}/form/model_spec.rb +0 -0
  105. data/spec/granite/form/types/active_support/time_zone_spec.rb +24 -0
  106. data/spec/granite/form/types/array_spec.rb +13 -0
  107. data/spec/granite/form/types/big_decimal_spec.rb +19 -0
  108. data/spec/granite/form/types/boolean_spec.rb +21 -0
  109. data/spec/granite/form/types/date_spec.rb +18 -0
  110. data/spec/granite/form/types/date_time_spec.rb +20 -0
  111. data/spec/granite/form/types/float_spec.rb +19 -0
  112. data/spec/granite/form/types/hash_with_action_controller_parameters_spec.rb +22 -0
  113. data/spec/granite/form/types/integer_spec.rb +18 -0
  114. data/spec/granite/form/types/object_spec.rb +40 -0
  115. data/spec/granite/form/types/string_spec.rb +13 -0
  116. data/spec/granite/form/types/time_spec.rb +31 -0
  117. data/spec/granite/form/types/uuid_spec.rb +21 -0
  118. data/spec/{lib/granite → granite}/form_spec.rb +0 -0
  119. data/spec/spec_helper.rb +0 -15
  120. data/spec/support/active_record.rb +20 -0
  121. data/spec/{shared → support/shared}/nested_attribute_examples.rb +3 -21
  122. data/spec/support/shared/type_examples.rb +7 -0
  123. metadata +173 -123
  124. data/.github/workflows/main.yml +0 -29
  125. data/gemfiles/rails.4.2.gemfile +0 -15
  126. data/lib/granite/form/model/callbacks.rb +0 -72
  127. data/lib/granite/form/model/lifecycle.rb +0 -309
  128. data/spec/lib/granite/form/model/associations/nested_attributes_spec.rb +0 -119
  129. data/spec/lib/granite/form/model/associations/references_many_spec.rb +0 -572
  130. data/spec/lib/granite/form/model/associations/references_one_spec.rb +0 -445
  131. data/spec/lib/granite/form/model/callbacks_spec.rb +0 -337
  132. data/spec/lib/granite/form/model/lifecycle_spec.rb +0 -356
  133. data/spec/lib/granite/form/model/typecasting_spec.rb +0 -193
@@ -3,38 +3,6 @@ module Granite
3
3
  module Model
4
4
  module Associations
5
5
  class ReferencesMany < ReferencesAny
6
- def build(attributes = {})
7
- append([build_object(attributes)]).last
8
- end
9
-
10
- def create(attributes = {})
11
- object = build(attributes)
12
- persist_object(object)
13
- object
14
- end
15
-
16
- def create!(attributes = {})
17
- object = build(attributes)
18
- persist_object(object, raise_error: true)
19
- object
20
- end
21
-
22
- def apply_changes
23
- target.all? do |object|
24
- if object
25
- if object.marked_for_destruction? && reflection.autosave?
26
- object.destroy
27
- elsif object.new_record? || (reflection.autosave? && object.changed?)
28
- persist_object(object)
29
- else
30
- true
31
- end
32
- else
33
- true
34
- end
35
- end
36
- end
37
-
38
6
  def target=(object)
39
7
  loaded!
40
8
  @target = object.to_a
@@ -3,34 +3,6 @@ module Granite
3
3
  module Model
4
4
  module Associations
5
5
  class ReferencesOne < ReferencesAny
6
- def build(attributes = {})
7
- replace(build_object(attributes))
8
- end
9
-
10
- def create(attributes = {})
11
- persist_object(build(attributes))
12
- target
13
- end
14
-
15
- def create!(attributes = {})
16
- persist_object(build(attributes), raise_error: true)
17
- target
18
- end
19
-
20
- def apply_changes
21
- if target
22
- if target.marked_for_destruction? && reflection.autosave?
23
- target.destroy
24
- elsif target.new_record? || (reflection.autosave? && target.changed?)
25
- persist_object(target)
26
- else
27
- true
28
- end
29
- else
30
- true
31
- end
32
- end
33
-
34
6
  def target=(object)
35
7
  loaded!
36
8
  @target = object
@@ -22,7 +22,7 @@ module Granite
22
22
  Class.new(superclass || Granite::Form.base_class) do
23
23
  include Granite::Form::Model
24
24
  include Granite::Form::Model::Associations
25
- include Granite::Form::Model::Lifecycle
25
+ include Granite::Form::Model::Persistence
26
26
  include Granite::Form::Model::Primary
27
27
  include Granite::Form.base_concern if Granite::Form.base_concern
28
28
  end
@@ -53,10 +53,6 @@ module Granite
53
53
  def inspect
54
54
  "#{self.class.name.demodulize}(#{persistence_adapter.data_type})"
55
55
  end
56
-
57
- def autosave?
58
- !!options[:autosave]
59
- end
60
56
  end
61
57
  end
62
58
  end
@@ -12,7 +12,9 @@ module Granite
12
12
 
13
13
  target.add_attribute(
14
14
  Granite::Form::Model::Attributes::Reflections::ReferenceMany,
15
- reflection.reference_key, association: name
15
+ reflection.reference_key,
16
+ type: reflection.persistence_adapter.primary_key_type,
17
+ association: name
16
18
  )
17
19
 
18
20
  reflection
@@ -7,14 +7,14 @@ module Granite
7
7
  module Associations
8
8
  module Reflections
9
9
  class ReferencesOne < ReferencesAny
10
- include Singular
11
-
12
10
  def self.build(target, generated_methods, name, *args, &block)
13
11
  reflection = super
14
12
 
15
13
  target.add_attribute(
16
14
  Granite::Form::Model::Attributes::Reflections::ReferenceOne,
17
- reflection.reference_key, association: name
15
+ reflection.reference_key,
16
+ type: reflection.persistence_adapter.primary_key_type,
17
+ association: name
18
18
  )
19
19
 
20
20
  reflection
@@ -14,14 +14,6 @@ module Granite
14
14
  def build_#{name} attributes = {}
15
15
  association(:#{name}).build(attributes)
16
16
  end
17
-
18
- def create_#{name} attributes = {}
19
- association(:#{name}).create(attributes)
20
- end
21
-
22
- def create_#{name}! attributes = {}
23
- association(:#{name}).create!(attributes)
24
- end
25
17
  RUBY
26
18
  end
27
19
  end
@@ -100,12 +100,6 @@ module Granite
100
100
  (@_associations ||= {})[reflection.name] ||= reflection.build_association(self)
101
101
  end
102
102
 
103
- def apply_association_changes!
104
- association_names.all? do |name|
105
- association(name).apply_changes!
106
- end
107
- end
108
-
109
103
  private
110
104
 
111
105
  def attributes_for_inspect
@@ -14,7 +14,7 @@ module Granite
14
14
 
15
15
  def read
16
16
  variable_cache(:value) do
17
- normalize(enumerize(typecast(read_before_type_cast)))
17
+ normalize(enumerize(type_definition.ensure_type(read_before_type_cast)))
18
18
  end
19
19
  end
20
20
 
@@ -3,19 +3,16 @@ module Granite
3
3
  module Model
4
4
  module Attributes
5
5
  class Base
6
- attr_reader :name, :owner
7
- delegate :type, :typecaster, :readonly, to: :reflection
6
+ attr_reader :owner, :reflection
7
+ delegate :name, :readonly, to: :reflection
8
+ delegate :type, to: :type_definition
8
9
 
9
- def initialize(name, owner)
10
- @name = name
10
+ def initialize(reflection, owner)
11
+ @reflection = reflection
11
12
  @owner = owner
12
13
  @origin = :default
13
14
  end
14
15
 
15
- def reflection
16
- @owner.class._attributes[name]
17
- end
18
-
19
16
  def write_value(value, origin: :user)
20
17
  reset
21
18
  @origin = origin
@@ -55,18 +52,14 @@ module Granite
55
52
  !(read.respond_to?(:zero?) ? read.zero? : read.blank?)
56
53
  end
57
54
 
58
- def typecast(value)
59
- if value.instance_of?(type)
60
- value
61
- else
62
- typecaster.call(value, self) unless value.nil?
63
- end
64
- end
65
-
66
55
  def readonly?
67
56
  !!(readonly.is_a?(Proc) ? evaluate(&readonly) : readonly)
68
57
  end
69
58
 
59
+ def type_definition
60
+ @type_definition ||= build_type_definition(reflection.type)
61
+ end
62
+
70
63
  def inspect_attribute
71
64
  value = case read
72
65
  when Date, Time, DateTime
@@ -103,11 +96,15 @@ module Granite
103
96
 
104
97
  private
105
98
 
99
+ def build_type_definition(type)
100
+ Granite::Form.type_for(type).new(type, reflection, owner)
101
+ end
102
+
106
103
  def evaluate(*args, &block)
107
104
  if block.arity >= 0 && block.arity <= args.length
108
105
  owner.instance_exec(*args.first(block.arity), &block)
109
106
  else
110
- args = block.arity < 0 ? args : args.first(block.arity)
107
+ args = block.arity.negative? ? args : args.first(block.arity)
111
108
  yield(*args, owner)
112
109
  end
113
110
  end
@@ -5,7 +5,7 @@ module Granite
5
5
  class Collection < Attribute
6
6
  def read
7
7
  @value ||= normalize(read_before_type_cast.map do |value|
8
- enumerize(typecast(value))
8
+ enumerize(type_definition.ensure_type(value))
9
9
  end)
10
10
  end
11
11
 
@@ -11,7 +11,7 @@ module Granite
11
11
  hash = hash.stringify_keys.slice(*keys) if keys.present?
12
12
 
13
13
  normalize(Hash[hash.map do |key, value|
14
- [key, enumerize(typecast(value))]
14
+ [key, enumerize(type_definition.ensure_type(value))]
15
15
  end].with_indifferent_access).with_indifferent_access
16
16
  end
17
17
  end
@@ -5,7 +5,7 @@ module Granite
5
5
  class Localized < Attribute
6
6
  def read
7
7
  @value ||= Hash[read_before_type_cast.map do |locale, value|
8
- [locale.to_s, normalize(enumerize(typecast(value)))]
8
+ [locale.to_s, normalize(enumerize(type_definition.ensure_type(value)))]
9
9
  end]
10
10
  end
11
11
 
@@ -5,7 +5,7 @@ module Granite
5
5
  class ReferenceMany < ReferenceOne
6
6
  def type_casted_value
7
7
  variable_cache(:value) do
8
- read_before_type_cast.map { |id| typecast(id) }
8
+ read_before_type_cast.map { |id| type_definition.ensure_type(id) }
9
9
  end
10
10
  end
11
11
 
@@ -24,7 +24,7 @@ module Granite
24
24
 
25
25
  def type_casted_value
26
26
  variable_cache(:value) do
27
- typecast(read_before_type_cast)
27
+ type_definition.ensure_type(read_before_type_cast)
28
28
  end
29
29
  end
30
30
 
@@ -32,14 +32,6 @@ module Granite
32
32
  @value_cache
33
33
  end
34
34
 
35
- def type
36
- @type ||= association.reflection.persistence_adapter.primary_key_type
37
- end
38
-
39
- def typecaster
40
- @typecaster ||= Granite::Form.typecaster(type.ancestors.grep(Class))
41
- end
42
-
43
35
  private
44
36
 
45
37
  def association
@@ -4,12 +4,6 @@ module Granite
4
4
  module Attributes
5
5
  module Reflections
6
6
  class Attribute < Base
7
- def self.build(target, generated_methods, name, *args, &block)
8
- attribute = super(target, generated_methods, name, *args, &block)
9
- generate_methods name, generated_methods
10
- attribute
11
- end
12
-
13
7
  def self.generate_methods(name, target)
14
8
  target.class_eval <<-RUBY, __FILE__, __LINE__ + 1
15
9
  def #{name}
@@ -7,11 +7,9 @@ module Granite
7
7
  attr_reader :name, :options
8
8
 
9
9
  class << self
10
- def build(_target, _generated_methods, name, *args, &block)
11
- options = args.extract_options!
12
- options[:type] = args.first if args.first
13
- options[:default] = block if block
14
- new(name, options)
10
+ def build(_target, generated_methods, name, *args, &block)
11
+ generate_methods name, generated_methods
12
+ new(name, *args, &block)
15
13
  end
16
14
 
17
15
  def generate_methods(name, target) end
@@ -21,13 +19,16 @@ module Granite
21
19
  end
22
20
  end
23
21
 
24
- def initialize(name, options = {})
22
+ def initialize(name, *args, &block)
25
23
  @name = name.to_s
26
- @options = options
24
+
25
+ @options = args.extract_options!
26
+ @options[:type] = args.first if args.first
27
+ @options[:default] = block if block
27
28
  end
28
29
 
29
30
  def build_attribute(owner, raw_value = Granite::Form::UNDEFINED)
30
- attribute = self.class.attribute_class.new(name, owner)
31
+ attribute = self.class.attribute_class.new(self, owner)
31
32
  attribute.write_value(raw_value, origin: :persistence) unless raw_value == Granite::Form::UNDEFINED
32
33
  attribute
33
34
  end
@@ -43,10 +44,6 @@ module Granite
43
44
  end
44
45
  end
45
46
 
46
- def typecaster
47
- @typecaster ||= Granite::Form.typecaster(type.ancestors.grep(Class))
48
- end
49
-
50
47
  def readonly
51
48
  @readonly ||= options[:readonly]
52
49
  end
@@ -4,12 +4,6 @@ module Granite
4
4
  module Attributes
5
5
  module Reflections
6
6
  class ReferenceOne < Base
7
- def self.build(_target, generated_methods, name, *args)
8
- options = args.extract_options!
9
- generate_methods name, generated_methods
10
- new(name, options)
11
- end
12
-
13
7
  def self.generate_methods(name, target)
14
8
  target.class_eval <<-RUBY, __FILE__, __LINE__ + 1
15
9
  def #{name}
@@ -30,10 +24,6 @@ module Granite
30
24
  RUBY
31
25
  end
32
26
 
33
- def type
34
- Object
35
- end
36
-
37
27
  def inspect_reflection
38
28
  "#{name}: (reference)"
39
29
  end
@@ -26,32 +26,14 @@ module Granite
26
26
  !!@persisted
27
27
  end
28
28
 
29
- def destroyed?
30
- !!@destroyed
31
- end
32
-
33
29
  def marked_for_destruction?
34
- @marked_for_destruction
35
- end
36
-
37
- def mark_for_destruction
38
- @marked_for_destruction = true
39
- end
40
-
41
- def _destroy
42
- marked_for_destruction?
30
+ false
43
31
  end
44
32
 
45
33
  private
46
34
 
47
35
  def mark_persisted!
48
36
  @persisted = true
49
- @destroyed = false
50
- end
51
-
52
- def mark_destroyed!
53
- @persisted = false
54
- @destroyed = true
55
37
  end
56
38
  end
57
39
  end
@@ -19,7 +19,7 @@ module Granite
19
19
  def self.import_errors(from, to, prefix)
20
20
  from.each do |error|
21
21
  key = "#{prefix}.#{error.attribute}"
22
- to.import(error, attribute: key) unless to.added?(key, error.type, error.options)
22
+ to.import(error, attribute: key) unless to.messages_for(key).include?(error.message)
23
23
  end
24
24
  end
25
25
  else
@@ -3,9 +3,7 @@ require 'granite/form/model/attributes'
3
3
  require 'granite/form/model/validations'
4
4
  require 'granite/form/model/scopes'
5
5
  require 'granite/form/model/primary'
6
- require 'granite/form/model/lifecycle'
7
6
  require 'granite/form/model/persistence'
8
- require 'granite/form/model/callbacks'
9
7
  require 'granite/form/model/associations'
10
8
  require 'granite/form/model/localization'
11
9
  require 'granite/form/model/representation'
@@ -0,0 +1,22 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ module ActiveSupport
7
+ class TimeZone < Float
8
+ def typecast(value)
9
+ case value
10
+ when ::ActiveSupport::TimeZone
11
+ value
12
+ when ::TZInfo::Timezone
13
+ ::ActiveSupport::TimeZone[value.name]
14
+ when ::String, ::Numeric, ::ActiveSupport::Duration
15
+ ::ActiveSupport::TimeZone[super || value]
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class Array < Object
7
+ def typecast(value)
8
+ if value.is_a?(::String)
9
+ value.split(',').map(&:strip)
10
+ else
11
+ super
12
+ end
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class BigDecimal < Object
7
+ def typecast(value)
8
+ BigDecimal(Float(value).to_s) if value
9
+ rescue ArgumentError, TypeError
10
+ nil
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class Boolean < Object
7
+ MAPPING = {
8
+ 1 => true,
9
+ 0 => false,
10
+ '1' => true,
11
+ '0' => false,
12
+ 't' => true,
13
+ 'f' => false,
14
+ 'T' => true,
15
+ 'F' => false,
16
+ true => true,
17
+ false => false,
18
+ 'true' => true,
19
+ 'false' => false,
20
+ 'TRUE' => true,
21
+ 'FALSE' => false,
22
+ 'y' => true,
23
+ 'n' => false,
24
+ 'yes' => true,
25
+ 'no' => false
26
+ }.freeze
27
+
28
+ def self.typecast(value)
29
+ MAPPING[value]
30
+ end
31
+
32
+ def typecast(value)
33
+ self.class.typecast(value)
34
+ end
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class Date < Object
7
+ def typecast(value)
8
+ value.try(:to_date)
9
+ rescue ArgumentError
10
+ nil
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class DateTime < Object
7
+ def typecast(value)
8
+ value.try(:to_datetime)
9
+ rescue ArgumentError
10
+ nil
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class Float < Object
7
+ def typecast(value)
8
+ Float(value)
9
+ rescue ArgumentError, TypeError
10
+ nil
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class HashWithActionControllerParameters < Object
7
+ def typecast(value)
8
+ case value
9
+ when ActionController::Parameters
10
+ value.to_h if value.permitted?
11
+ when ::Hash then
12
+ value
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class Integer < Float
7
+ def typecast(value)
8
+ super.try(:to_i)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class Object
7
+ attr_reader :reflection, :owner, :type
8
+ delegate :name, to: :reflection
9
+
10
+ def initialize(type, reflection, owner)
11
+ @type = type
12
+ @reflection = reflection
13
+ @owner = owner
14
+ end
15
+
16
+ def ensure_type(value)
17
+ if value.instance_of?(type)
18
+ value
19
+ elsif !value.nil?
20
+ typecast(value)
21
+ end
22
+ end
23
+
24
+ def typecast(value)
25
+ value if value.is_a?(type)
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Granite
4
+ module Form
5
+ module Types
6
+ class String < Object
7
+ def typecast(value)
8
+ value.to_s
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end