granite-form 0.4.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/.github/CODEOWNERS +1 -1
  3. data/.github/workflows/ruby.yml +3 -5
  4. data/.rubocop.yml +26 -48
  5. data/.rubocop_todo.yml +304 -27
  6. data/Appraisals +1 -1
  7. data/CHANGELOG.md +15 -2
  8. data/gemfiles/{rails.5.0.gemfile → rails.7.1.gemfile} +3 -3
  9. data/granite-form.gemspec +6 -5
  10. data/lib/granite/form/active_record/associations.rb +4 -3
  11. data/lib/granite/form/config.rb +1 -1
  12. data/lib/granite/form/errors.rb +34 -32
  13. data/lib/granite/form/extensions.rb +2 -1
  14. data/lib/granite/form/model/associations/base.rb +6 -2
  15. data/lib/granite/form/model/associations/collection/embedded.rb +1 -1
  16. data/lib/granite/form/model/associations/collection/proxy.rb +3 -3
  17. data/lib/granite/form/model/associations/embeds_any.rb +1 -1
  18. data/lib/granite/form/model/associations/embeds_many.rb +15 -11
  19. data/lib/granite/form/model/associations/embeds_one.rb +9 -8
  20. data/lib/granite/form/model/associations/nested_attributes.rb +60 -32
  21. data/lib/granite/form/model/associations/persistence_adapters/active_record/referenced_proxy.rb +2 -1
  22. data/lib/granite/form/model/associations/persistence_adapters/active_record.rb +7 -6
  23. data/lib/granite/form/model/associations/persistence_adapters/base.rb +8 -4
  24. data/lib/granite/form/model/associations/references_any.rb +1 -1
  25. data/lib/granite/form/model/associations/references_many.rb +3 -2
  26. data/lib/granite/form/model/associations/references_one.rb +1 -1
  27. data/lib/granite/form/model/associations/reflections/base.rb +3 -2
  28. data/lib/granite/form/model/associations/reflections/embeds_any.rb +4 -4
  29. data/lib/granite/form/model/associations/reflections/embeds_many.rb +4 -1
  30. data/lib/granite/form/model/associations/reflections/embeds_one.rb +4 -1
  31. data/lib/granite/form/model/associations/reflections/references_any.rb +6 -6
  32. data/lib/granite/form/model/associations/reflections/references_many.rb +1 -1
  33. data/lib/granite/form/model/associations/reflections/references_one.rb +1 -1
  34. data/lib/granite/form/model/associations/validations.rb +6 -6
  35. data/lib/granite/form/model/associations.rb +6 -4
  36. data/lib/granite/form/model/attributes/attribute.rb +1 -0
  37. data/lib/granite/form/model/attributes/base.rb +9 -7
  38. data/lib/granite/form/model/attributes/reference_one.rb +1 -1
  39. data/lib/granite/form/model/attributes/reflections/base/build_type_definition.rb +2 -1
  40. data/lib/granite/form/model/attributes/reflections/represents/build_type_definition.rb +2 -2
  41. data/lib/granite/form/model/attributes/represents.rb +1 -1
  42. data/lib/granite/form/model/attributes.rb +21 -13
  43. data/lib/granite/form/model/conventions.rb +1 -1
  44. data/lib/granite/form/model/persistence.rb +1 -1
  45. data/lib/granite/form/model/primary.rb +1 -1
  46. data/lib/granite/form/model/representation.rb +4 -4
  47. data/lib/granite/form/model/scopes.rb +5 -5
  48. data/lib/granite/form/model/validations.rb +4 -3
  49. data/lib/granite/form/types/active_support/time_zone.rb +1 -1
  50. data/lib/granite/form/types/array.rb +1 -1
  51. data/lib/granite/form/types/big_decimal.rb +1 -1
  52. data/lib/granite/form/types/boolean.rb +1 -1
  53. data/lib/granite/form/types/date.rb +1 -1
  54. data/lib/granite/form/types/date_time.rb +1 -1
  55. data/lib/granite/form/types/dictionary.rb +1 -1
  56. data/lib/granite/form/types/float.rb +1 -1
  57. data/lib/granite/form/types/has_subtype.rb +1 -0
  58. data/lib/granite/form/types/hash_with_action_controller_parameters.rb +2 -2
  59. data/lib/granite/form/types/integer.rb +1 -1
  60. data/lib/granite/form/types/object.rb +2 -1
  61. data/lib/granite/form/types/string.rb +1 -1
  62. data/lib/granite/form/types/time.rb +1 -1
  63. data/lib/granite/form/types/uuid.rb +1 -1
  64. data/lib/granite/form/util.rb +1 -1
  65. data/lib/granite/form/version.rb +1 -1
  66. data/spec/granite/form/active_record/associations_spec.rb +35 -13
  67. data/spec/granite/form/config_spec.rb +8 -4
  68. data/spec/granite/form/model/associations/embeds_many_spec.rb +99 -51
  69. data/spec/granite/form/model/associations/embeds_one_spec.rb +48 -25
  70. data/spec/granite/form/model/associations/persistence_adapters/active_record_spec.rb +12 -7
  71. data/spec/granite/form/model/associations/references_many_spec.rb +51 -10
  72. data/spec/granite/form/model/associations/references_one_spec.rb +17 -6
  73. data/spec/granite/form/model/associations/reflections/embeds_many_spec.rb +51 -16
  74. data/spec/granite/form/model/associations/reflections/embeds_one_spec.rb +19 -9
  75. data/spec/granite/form/model/associations/reflections/references_many_spec.rb +67 -15
  76. data/spec/granite/form/model/associations/reflections/references_one_spec.rb +34 -11
  77. data/spec/granite/form/model/associations/validations_spec.rb +16 -5
  78. data/spec/granite/form/model/associations_spec.rb +28 -9
  79. data/spec/granite/form/model/attributes/attribute_spec.rb +33 -11
  80. data/spec/granite/form/model/attributes/base_spec.rb +26 -2
  81. data/spec/granite/form/model/attributes/reflections/attribute_spec.rb +1 -0
  82. data/spec/granite/form/model/attributes/reflections/base_spec.rb +1 -0
  83. data/spec/granite/form/model/attributes/reflections/represents/build_type_definition_spec.rb +3 -1
  84. data/spec/granite/form/model/attributes/reflections/represents_spec.rb +2 -2
  85. data/spec/granite/form/model/attributes/represents_spec.rb +2 -2
  86. data/spec/granite/form/model/attributes_spec.rb +76 -36
  87. data/spec/granite/form/model/dirty_spec.rb +3 -0
  88. data/spec/granite/form/model/persistence_spec.rb +15 -5
  89. data/spec/granite/form/model/primary_spec.rb +17 -2
  90. data/spec/granite/form/model/representation_spec.rb +13 -3
  91. data/spec/granite/form/model/scopes_spec.rb +8 -3
  92. data/spec/granite/form/model/validations/associated_spec.rb +20 -6
  93. data/spec/granite/form/model/validations/nested_spec.rb +30 -14
  94. data/spec/granite/form/model/validations_spec.rb +1 -1
  95. data/spec/granite/form/model_spec.rb +1 -0
  96. data/spec/granite/form/types/collection_spec.rb +2 -1
  97. data/spec/granite/form/types/date_spec.rb +1 -1
  98. data/spec/granite/form/types/date_time_spec.rb +0 -2
  99. data/spec/granite/form/types/dictionary_spec.rb +1 -0
  100. data/spec/granite/form/types/has_subtype_spec.rb +6 -1
  101. data/spec/granite/form/types/hash_with_action_controller_parameters_spec.rb +1 -1
  102. data/spec/granite/form/types/object_spec.rb +2 -0
  103. data/spec/granite/form/types/time_spec.rb +0 -2
  104. data/spec/granite/form/util_spec.rb +6 -3
  105. data/spec/support/active_record.rb +13 -0
  106. data/spec/support/shared/nested_attribute_examples.rb +110 -54
  107. metadata +28 -16
  108. data/gemfiles/rails.5.1.gemfile +0 -14
  109. data/gemfiles/rails.5.2.gemfile +0 -14
@@ -13,53 +13,55 @@ module Granite
13
13
  def initialize(model)
14
14
  @model = model
15
15
  errors = @model.errors.full_messages.join(', ')
16
- super(I18n.t(:"#{@model.class.i18n_scope}.errors.messages.model_invalid", errors: errors, default: :'errors.messages.model_invalid'))
16
+ super(I18n.t(:"#{@model.class.i18n_scope}.errors.messages.model_invalid",
17
+ errors: errors, default: :'errors.messages.model_invalid'))
17
18
  end
18
19
  end
19
20
 
20
21
  class AssociationTypeMismatch < Error
21
22
  def initialize(expected, got)
22
- super "Expected `#{expected}` (##{expected.object_id}), but got `#{got}` (##{got.object_id})"
23
+ super("Expected `#{expected}` (##{expected.object_id}), but got `#{got}` (##{got.object_id})")
23
24
  end
24
25
  end
25
26
 
26
27
  class ObjectNotFound < Error
27
28
  def initialize(object, association_name, record_id)
29
+ primary_name = object.respond_to?(:_primary_name) ? object._primary_name : 'id'
28
30
  message = "Couldn't find #{object.class.reflect_on_association(association_name).klass.name}" \
29
- "with #{object.respond_to?(:_primary_name) ? object._primary_name : 'id'} = #{record_id} for #{object.inspect}"
30
- super message
31
+ "with #{primary_name} = #{record_id} for #{object.inspect}"
32
+ super(message)
31
33
  end
32
34
  end
33
35
 
34
36
  class TooManyObjects < Error
35
37
  def initialize(limit, actual_size)
36
- super "Maximum #{limit} objects are allowed. Got #{actual_size} objects instead."
38
+ super("Maximum #{limit} objects are allowed. Got #{actual_size} objects instead.")
37
39
  end
38
40
  end
39
41
 
40
42
  class UndefinedPrimaryAttribute < Error
41
43
  def initialize(klass, association_name)
42
- super <<-MESSAGE
43
- Undefined primary attribute for `#{association_name}` in #{klass}.
44
- It is required for embeds_many nested attributes proper operation.
45
- You can define this association as:
44
+ super(<<~MESSAGE)
45
+ Undefined primary attribute for `#{association_name}` in #{klass}.
46
+ It is required for embeds_many nested attributes proper operation.
47
+ You can define this association as:
46
48
 
47
- embeds_many :#{association_name} do
48
- primary :attribute_name
49
- end
49
+ embeds_many :#{association_name} do
50
+ primary :attribute_name
51
+ end
50
52
  MESSAGE
51
53
  end
52
54
  end
53
55
 
54
56
  class NormalizerMissing < NoMethodError
55
57
  def initialize(name)
56
- super <<-MESSAGE
57
- Could not find normalizer `:#{name}`
58
- You can define it with:
58
+ super(<<~MESSAGE)
59
+ Could not find normalizer `:#{name}`
60
+ You can define it with:
59
61
 
60
- Granite::Form.normalizer(:#{name}) do |value, options|
61
- # do some staff with value and options
62
- end
62
+ Granite::Form.normalizer(:#{name}) do |value, options|
63
+ # do some staff with value and options
64
+ end
63
65
  MESSAGE
64
66
  end
65
67
  end
@@ -67,28 +69,28 @@ You can define it with:
67
69
  class TypecasterMissing < NoMethodError
68
70
  def initialize(*classes)
69
71
  classes = classes.flatten
70
- super <<-MESSAGE
71
- Could not find typecaster for #{classes}
72
- You can define it with:
72
+ super(<<~MESSAGE)
73
+ Could not find typecaster for #{classes}
74
+ You can define it with:
73
75
 
74
- Granite::Form.typecaster('#{classes.first}') do |value|
75
- # do some staff with value and options
76
- end
76
+ Granite::Form.typecaster('#{classes.first}') do |value|
77
+ # do some staff with value and options
78
+ end
77
79
  MESSAGE
78
80
  end
79
81
  end
80
82
 
81
83
  class PersistenceAdapterMissing < NoMethodError
82
84
  def initialize(data_source)
83
- super <<-MESSAGE
84
- Could not find persistence adapter for #{data_source}
85
- You can define it with:
85
+ super(<<~MESSAGE)
86
+ Could not find persistence adapter for #{data_source}
87
+ You can define it with:
86
88
 
87
- class #{data_source}
88
- def self.granite_persistence_adapter
89
- #{data_source}GraniteFormPersistenceAdapter
90
- end
91
- end
89
+ class #{data_source}
90
+ def self.granite_persistence_adapter
91
+ #{data_source}GraniteFormPersistenceAdapter
92
+ end
93
+ end
92
94
  MESSAGE
93
95
  end
94
96
  end
@@ -17,7 +17,8 @@ else
17
17
  end
18
18
 
19
19
  def self.parse_string(value)
20
- return nil if value.length.zero?
20
+ return nil if value.empty?
21
+
21
22
  if value.length == 36
22
23
  parse value
23
24
  elsif value.length == 32
@@ -4,6 +4,7 @@ module Granite
4
4
  module Associations
5
5
  class Base
6
6
  attr_accessor :owner, :reflection
7
+
7
8
  delegate :macro, :collection?, to: :reflection
8
9
 
9
10
  def initialize(owner, reflection)
@@ -33,6 +34,7 @@ module Granite
33
34
 
34
35
  def target
35
36
  return @target if loaded?
37
+
36
38
  self.target = load_target
37
39
  end
38
40
 
@@ -66,10 +68,12 @@ module Granite
66
68
  end
67
69
 
68
70
  def inspect
69
- "#<#{reflection.macro.to_s.camelize} #{target.inspect.truncate(50, omission: collection? ? '...]' : '...')}>"
71
+ macro = reflection.macro.to_s.camelize
72
+ target_for_inspect = target.inspect.truncate(50, omission: collection? ? '...]' : '...')
73
+ "#<#{macro} #{target_for_inspect}>"
70
74
  end
71
75
 
72
- private
76
+ private
73
77
 
74
78
  def read_source
75
79
  reflection.read_source owner
@@ -6,7 +6,7 @@ module Granite
6
6
  class Embedded < Proxy
7
7
  delegate :build, to: :@association
8
8
  delegate :delete, to: :target
9
- alias_method :new, :build
9
+ alias new build
10
10
  end
11
11
  end
12
12
  end
@@ -8,8 +8,8 @@ module Granite
8
8
 
9
9
  delegate :target, :loaded?, :reload, :clear, :concat, to: :@association
10
10
  delegate :each, :size, :length, :first, :last, :empty?, :many?, :==, :dup, to: :target
11
- alias_method :<<, :concat
12
- alias_method :push, :concat
11
+ alias << concat
12
+ alias push concat
13
13
 
14
14
  def initialize(association)
15
15
  @association = association
@@ -19,7 +19,7 @@ module Granite
19
19
  dup
20
20
  end
21
21
 
22
- alias_method :to_a, :to_ary
22
+ alias to_a to_ary
23
23
 
24
24
  def inspect
25
25
  entries = target.take(10).map!(&:inspect)
@@ -3,7 +3,7 @@ module Granite
3
3
  module Model
4
4
  module Associations
5
5
  class EmbedsAny < Base
6
- private
6
+ private
7
7
 
8
8
  def build_object(attributes)
9
9
  reflection.klass.new(attributes)
@@ -23,14 +23,14 @@ module Granite
23
23
  default = Array.wrap(reflection.default(owner))
24
24
  if default.present?
25
25
  collection = if default.all? { |object| object.is_a?(reflection.klass) }
26
- default
27
- else
28
- default.map do |attributes|
29
- reflection.klass.with_sanitize(false) do
30
- build_object(attributes)
31
- end
32
- end
33
- end
26
+ default
27
+ else
28
+ default.map do |attributes|
29
+ reflection.klass.with_sanitize(false) do
30
+ build_object(attributes)
31
+ end
32
+ end
33
+ end
34
34
  collection.map { |object| object.send(:clear_changes_information) } if reflection.klass.dirty?
35
35
  collection
36
36
  end
@@ -64,13 +64,13 @@ module Granite
64
64
  end
65
65
  end
66
66
 
67
- alias_method :writer, :replace
67
+ alias writer replace
68
68
 
69
69
  def concat(*objects)
70
70
  append objects.flatten
71
71
  end
72
72
 
73
- private
73
+ private
74
74
 
75
75
  def read_source
76
76
  super || []
@@ -78,7 +78,11 @@ module Granite
78
78
 
79
79
  def append(objects)
80
80
  objects.each do |object|
81
- raise AssociationTypeMismatch.new(reflection.klass, object.class) unless object && object.is_a?(reflection.klass)
81
+ unless object.is_a?(reflection.klass)
82
+ raise AssociationTypeMismatch.new(reflection.klass,
83
+ object.class)
84
+ end
85
+
82
86
  push_object object
83
87
  end
84
88
  target
@@ -30,12 +30,12 @@ module Granite
30
30
  return unless default
31
31
 
32
32
  object = if default.is_a?(reflection.klass)
33
- default
34
- else
35
- reflection.klass.with_sanitize(false) do
36
- build_object(default)
37
- end
38
- end
33
+ default
34
+ else
35
+ reflection.klass.with_sanitize(false) do
36
+ build_object(default)
37
+ end
38
+ end
39
39
  object.send(:clear_changes_information) if reflection.klass.dirty?
40
40
  object
41
41
  end
@@ -58,6 +58,7 @@ module Granite
58
58
  def replace(object)
59
59
  if object
60
60
  raise AssociationTypeMismatch.new(reflection.klass, object.class) unless object.is_a?(reflection.klass)
61
+
61
62
  transaction do
62
63
  clear
63
64
  self.target = object
@@ -69,9 +70,9 @@ module Granite
69
70
  target
70
71
  end
71
72
 
72
- alias_method :writer, :replace
73
+ alias writer replace
73
74
 
74
- private
75
+ private
75
76
 
76
77
  def setup_performers!(object)
77
78
  embed_object(object)
@@ -22,7 +22,7 @@ module Granite
22
22
  attrs = attrs.stringify_keys
23
23
 
24
24
  nested_attrs = self.class.nested_attributes_options.keys
25
- .each_with_object({}) do |association_name, result|
25
+ .each_with_object({}) do |association_name, result|
26
26
  name = "#{association_name}_attributes"
27
27
  result[name] = attrs.delete(name) if attrs.key?(name)
28
28
  end
@@ -33,14 +33,18 @@ module Granite
33
33
  end
34
34
  end
35
35
 
36
- alias_method :attributes=, :assign_attributes
36
+ alias attributes= assign_attributes
37
37
  end
38
38
 
39
- class NestedAttributesMethods
40
- REJECT_ALL_BLANK_PROC = proc { |attributes| attributes.all? { |key, value| key == DESTROY_ATTRIBUTE || value.blank? } }
39
+ class NestedAttributesMethods # rubocop:disable Metrics/ClassLength
40
+ REJECT_ALL_BLANK_PROC = proc { |attributes|
41
+ attributes.all? do |key, value|
42
+ key == DESTROY_ATTRIBUTE || value.blank?
43
+ end
44
+ }
41
45
 
42
46
  def self.accepts_nested_attributes_for(klass, *attr_names)
43
- options = {allow_destroy: false, update_only: false}
47
+ options = { allow_destroy: false, update_only: false }
44
48
  options.update(attr_names.extract_options!)
45
49
  options.assert_valid_keys(:allow_destroy, :reject_if, :limit, :update_only)
46
50
  options[:reject_if] = REJECT_ALL_BLANK_PROC if options[:reject_if] == :all_blank
@@ -49,10 +53,18 @@ module Granite
49
53
 
50
54
  attr_names.each do |association_name|
51
55
  reflection = klass.reflect_on_association(association_name)
52
- raise ArgumentError, "No association found for name `#{association_name}'. Has it been defined yet?" unless reflection
53
- klass.nested_attributes_options = klass.nested_attributes_options.merge(association_name.to_sym => options)
56
+ unless reflection
57
+ raise ArgumentError,
58
+ "No association found for name `#{association_name}'. Has it been defined yet?"
59
+ end
60
+
61
+ klass.nested_attributes_options =
62
+ klass
63
+ .nested_attributes_options
64
+ .merge(association_name.to_sym => options)
54
65
 
55
- should_validate_nested = klass.respond_to?(:validates_nested) && !klass.validates_nested?(association_name)
66
+ should_validate_nested = klass.respond_to?(:validates_nested) &&
67
+ !klass.validates_nested?(association_name)
56
68
  klass.validates_nested(association_name) if should_validate_nested
57
69
 
58
70
  type = (reflection.collection? ? :collection : :one_to_one)
@@ -74,10 +86,17 @@ module Granite
74
86
  primary_attribute_name = primary_name_for(association.reflection.klass)
75
87
  if existing_record
76
88
  primary_attribute = existing_record.attribute(primary_attribute_name)
77
- primary_attribute_value = primary_attribute.type_definition.prepare(attributes[primary_attribute_name]) if primary_attribute
89
+ if primary_attribute
90
+ primary_attribute_value = primary_attribute.type_definition
91
+ .prepare(attributes[primary_attribute_name])
92
+ end
78
93
  end
79
94
 
80
- if existing_record && (!primary_attribute || options[:update_only] || existing_record.primary_attribute == primary_attribute_value)
95
+ should_assign = !primary_attribute ||
96
+ options[:update_only] ||
97
+ existing_record.primary_attribute == primary_attribute_value
98
+
99
+ if existing_record && should_assign
81
100
  assign_to(existing_record, attributes) unless call_reject_if(object, association_name, attributes)
82
101
  association.clear if destroy_flag?(attributes) && options[:allow_destroy]
83
102
  elsif attributes[primary_attribute_name].present?
@@ -93,11 +112,12 @@ module Granite
93
112
  end
94
113
  end
95
114
 
96
- def self.assign_nested_attributes_for_collection_association(object, association_name, attributes_collection)
115
+ def self.assign_nested_attributes_for_collection_association(object, association_name, attributes_collection) # rubocop:disable Layout/LineLength,Metrics/MethodLength
97
116
  options = object.nested_attributes_options[association_name]
98
117
 
99
118
  unless attributes_collection.is_a?(Hash) || attributes_collection.is_a?(Array)
100
- raise ArgumentError, "Hash or Array expected, got #{attributes_collection.class.name} (#{attributes_collection.inspect})"
119
+ raise ArgumentError,
120
+ "Hash or Array expected, got #{attributes_collection.class.name} (#{attributes_collection.inspect})" # rubocop:disable Layout/LineLength
101
121
  end
102
122
 
103
123
  check_record_limit!(options[:limit], attributes_collection)
@@ -105,26 +125,32 @@ module Granite
105
125
  association = object.association(association_name)
106
126
  primary_attribute_name = primary_name_for(association.reflection.klass)
107
127
 
108
- raise Granite::Form::UndefinedPrimaryAttribute.new(object.class, association_name) unless primary_attribute_name
128
+ unless primary_attribute_name
129
+ raise Granite::Form::UndefinedPrimaryAttribute.new(object.class,
130
+ association_name)
131
+ end
109
132
 
110
133
  if attributes_collection.is_a? Hash
111
134
  keys = attributes_collection.keys
112
- attributes_collection = if keys.include?(primary_attribute_name) || keys.include?(primary_attribute_name.to_sym)
113
- [attributes_collection]
114
- else
115
- attributes_collection.values
116
- end
135
+ attributes_collection =
136
+ if keys.include?(primary_attribute_name) || keys.include?(primary_attribute_name.to_sym)
137
+ [attributes_collection]
138
+ else
139
+ attributes_collection.values
140
+ end
117
141
  end
118
142
 
119
143
  attributes_collection.each do |attributes|
120
144
  attributes = attributes.with_indifferent_access
121
145
 
122
146
  if attributes[primary_attribute_name].blank?
123
- association.build(attributes.except(*unassignable_keys(object))) unless reject_new_object?(object, association_name, attributes, options)
147
+ association.build(attributes.except(*unassignable_keys(object))) unless reject_new_object?(
148
+ object, association_name, attributes, options
149
+ )
124
150
  else
125
151
  existing_record = association.target.detect do |record|
126
152
  primary_attribute_value = record.attribute(primary_attribute_name)
127
- .type_definition.prepare(attributes[primary_attribute_name])
153
+ .type_definition.prepare(attributes[primary_attribute_name])
128
154
  record.primary_attribute == primary_attribute_value
129
155
  end
130
156
  if existing_record
@@ -137,7 +163,8 @@ module Granite
137
163
  end
138
164
  end
139
165
  else
140
- raise Granite::Form::ObjectNotFound.new(object, association_name, attributes[primary_attribute_name])
166
+ raise Granite::Form::ObjectNotFound.new(object, association_name,
167
+ attributes[primary_attribute_name])
141
168
  end
142
169
  end
143
170
  end
@@ -145,13 +172,13 @@ module Granite
145
172
 
146
173
  def self.check_record_limit!(limit, attributes_collection)
147
174
  limit = case limit
148
- when Symbol
149
- send(limit)
150
- when Proc
151
- limit.call
152
- else
153
- limit
154
- end
175
+ when Symbol
176
+ send(limit)
177
+ when Proc
178
+ limit.call
179
+ else
180
+ limit
181
+ end
155
182
 
156
183
  return unless limit && attributes_collection.size > limit
157
184
 
@@ -197,15 +224,16 @@ module Granite
197
224
  module NestedAttributesMethodsExtension
198
225
  def self.ensure_extended!(klass)
199
226
  return if klass.singleton_class.ancestors.include?(self)
227
+
200
228
  klass.extend(self)
201
229
  end
202
230
 
203
231
  def nested_attributes_methods_module
204
232
  @nested_attributes_methods_module ||= begin
205
- mod = const_set(:NestedAttributesMethods, Module.new)
206
- include(mod)
207
- mod
208
- end
233
+ mod = const_set(:NestedAttributesMethods, Module.new)
234
+ include(mod)
235
+ mod
236
+ end
209
237
  end
210
238
  end
211
239
  end
@@ -9,6 +9,7 @@ module Granite
9
9
  METHODS_EXCLUDED_FROM_DELEGATION = %w[build create create!].map(&:to_sym).freeze
10
10
 
11
11
  attr_reader :association
12
+
12
13
  delegate :scope, to: :@association
13
14
 
14
15
  def method_missing(method, *args, &block)
@@ -19,7 +20,7 @@ module Granite
19
20
  delegate_to_scope?(method) || super
20
21
  end
21
22
 
22
- private
23
+ private
23
24
 
24
25
  def delegate_to_scope?(method)
25
26
  METHODS_EXCLUDED_FROM_DELEGATION.exclude?(method) && scope.respond_to?(method)
@@ -17,10 +17,11 @@ module Granite
17
17
  text: String,
18
18
  string: String,
19
19
  binary: String,
20
- boolean: Boolean
20
+ boolean: Boolean,
21
+ enum: String
21
22
  }.freeze
22
23
 
23
- alias_method :data_type, :data_source
24
+ alias data_type data_source
24
25
 
25
26
  def build(attributes)
26
27
  data_source.new(attributes)
@@ -31,10 +32,10 @@ module Granite
31
32
 
32
33
  if scope_proc
33
34
  scope = if scope_proc.arity.zero?
34
- scope.instance_exec(&scope_proc)
35
- else
36
- scope.instance_exec(owner, &scope_proc)
37
- end
35
+ scope.instance_exec(&scope_proc)
36
+ else
37
+ scope.instance_exec(owner, &scope_proc)
38
+ end
38
39
  end
39
40
 
40
41
  scope.where(primary_key => source)
@@ -13,7 +13,8 @@ module Granite
13
13
  end
14
14
 
15
15
  def build(_attributes)
16
- raise NotImplementedError, 'Should be implemented in inhereted adapter. Build new instance of data object by attributes'
16
+ raise NotImplementedError,
17
+ 'Should be implemented in inhereted adapter. Build new instance of data object by attributes'
17
18
  end
18
19
 
19
20
  def scope(_owner, _source)
@@ -29,11 +30,13 @@ module Granite
29
30
  end
30
31
 
31
32
  def identify(_object)
32
- raise NotImplementedError, 'Should be implemented in inhereted adapter. Field to be used as primary_key for object'
33
+ raise NotImplementedError,
34
+ 'Should be implemented in inhereted adapter. Field to be used as primary_key for object'
33
35
  end
34
36
 
35
37
  def data_type
36
- raise NotImplementedError, 'Should be implemented in inhereted adapter. Type of data object for type_check'
38
+ raise NotImplementedError,
39
+ 'Should be implemented in inhereted adapter. Type of data object for type_check'
37
40
  end
38
41
 
39
42
  def primary_key_type
@@ -41,7 +44,8 @@ module Granite
41
44
  end
42
45
 
43
46
  def referenced_proxy
44
- raise NotImplementedError, 'Should be implemented in inhereted adapter. Object to manage proxying of methods to scope.'
47
+ raise NotImplementedError,
48
+ 'Should be implemented in inhereted adapter. Object to manage proxying of methods to scope.'
45
49
  end
46
50
  end
47
51
  end
@@ -7,7 +7,7 @@ module Granite
7
7
  reflection.persistence_adapter.scope(owner, source)
8
8
  end
9
9
 
10
- private
10
+ private
11
11
 
12
12
  def read_source
13
13
  attribute.read_before_type_cast
@@ -42,7 +42,7 @@ module Granite
42
42
  end
43
43
  end
44
44
 
45
- alias_method :writer, :replace
45
+ alias writer replace
46
46
 
47
47
  def concat(*objects)
48
48
  append objects.flatten
@@ -60,12 +60,13 @@ module Granite
60
60
  target.map { |obj| reflection.persistence_adapter.identify(obj) }
61
61
  end
62
62
 
63
- private
63
+ private
64
64
 
65
65
  def append(objects)
66
66
  attribute.pollute do
67
67
  objects.each do |object|
68
68
  next if target.include?(object)
69
+
69
70
  raise_type_mismatch(object) unless matches_type?(object)
70
71
 
71
72
  target.push(object)
@@ -48,7 +48,7 @@ module Granite
48
48
  target
49
49
  end
50
50
 
51
- alias_method :writer, :replace
51
+ alias writer replace
52
52
 
53
53
  def identify
54
54
  reflection.persistence_adapter.identify(target)
@@ -10,13 +10,14 @@ module Granite
10
10
  attr_reader :name, :options
11
11
  # AR compatibility
12
12
  attr_accessor :parent_reflection
13
+
13
14
  delegate :association_class, to: 'self.class'
14
15
 
15
16
  def self.build(target, generated_methods, name, options = {}, &_block)
16
17
  generate_methods name, generated_methods
17
18
  if options.delete(:validate) &&
18
- target.respond_to?(:validates_nested) &&
19
- !target.validates_nested?(name)
19
+ target.respond_to?(:validates_nested) &&
20
+ !target.validates_nested?(name)
20
21
  target.validates_nested name
21
22
  end
22
23
  new(name, options)
@@ -31,10 +31,10 @@ module Granite
31
31
 
32
32
  def klass
33
33
  @klass ||= if options[:class]
34
- options[:class].call(self)
35
- else
36
- super
37
- end
34
+ options[:class].call(self)
35
+ else
36
+ super
37
+ end
38
38
  end
39
39
 
40
40
  def inspect
@@ -5,7 +5,10 @@ module Granite
5
5
  module Reflections
6
6
  class EmbedsMany < EmbedsAny
7
7
  def self.build(target, generated_methods, name, options = {}, &block)
8
- target.add_attribute(Granite::Form::Model::Attributes::Reflections::Base, name, type: Object) if target < Granite::Form::Model::Attributes
8
+ if target < Granite::Form::Model::Attributes
9
+ target.add_attribute(Granite::Form::Model::Attributes::Reflections::Base, name,
10
+ type: Object)
11
+ end
9
12
  options[:validate] = true unless options.key?(:validate)
10
13
  super
11
14
  end
@@ -7,7 +7,10 @@ module Granite
7
7
  include Singular
8
8
 
9
9
  def self.build(target, generated_methods, name, options = {}, &block)
10
- target.add_attribute(Granite::Form::Model::Attributes::Reflections::Base, name, type: Object) if target < Granite::Form::Model::Attributes
10
+ if target < Granite::Form::Model::Attributes
11
+ target.add_attribute(Granite::Form::Model::Attributes::Reflections::Base, name,
12
+ type: Object)
13
+ end
11
14
  options[:validate] = true unless options.key?(:validate)
12
15
  super
13
16
  end