Module: ApiRegulator::AttributeDefinitionMixin

Extended by:
ActiveSupport::Concern
Included in:
Validator
Defined in:
lib/api_regulator/validator.rb

Instance Method Summary collapse

Instance Method Details

#validate_array_of_objects(attribute, item_validator_class, param) ⇒ Object

Instance methods



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/api_regulator/validator.rb', line 115

def validate_array_of_objects(attribute, item_validator_class, param)
  raw_value = @raw_attributes[attribute]

  # Ensure the presence check works only on the array itself, not its contents
  if raw_value.blank?
    errors.add(attribute, "can't be blank") if param.options[:presence]
    return
  end

  unless raw_value.is_a?(Array)
    errors.add(attribute, "must be an array")
    return
  end

  if max = param.options.dig(:length, :maximum)
    errors.add(attribute, "must have a max size of #{max}") if raw_value.length > max
    return
  end

  raw_value.each_with_index do |value, index|
    unless value.is_a?(Hash) || value.is_a?(ActionController::Parameters)
      errors.add("#{attribute}[#{index}]", "must be a hash")
      next
    end

    validator = item_validator_class.new(value)
    unless validator.valid?(validation_context)
      validator.errors.each do |error|
        nested_attr = "#{attribute}[#{index}].#{error.attribute}"
        errors.add(nested_attr, error.message)
      end
    end
  end
end

#validate_array_of_scalars(attribute, param) ⇒ Object



150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/api_regulator/validator.rb', line 150

def validate_array_of_scalars(attribute, param)
  raw_value = @raw_attributes[attribute]

  if raw_value.nil?
    errors.add(attribute, "can't be blank") if param.options[:presence]
    return
  end

  unless raw_value.is_a?(Array)
    errors.add(attribute, "must be an array")
    return
  end

  inclusion_list = param.options.dig(:inclusion, :in)

  raw_value.each_with_index do |value, index|
    # Skip type and inclusion validation if nil is allowed and value is nil
    if value.nil? && (inclusion_list&.include?(nil) || param.options.dig(:inclusion, :allow_nil))
      next
    end

    # Type validation for non-nil values
    case param.item_type
    when :string
      unless value.is_a?(String)
        errors.add("#{attribute}[#{index}]", "must be a string")
        next
      end
    when :integer
      unless value.is_a?(Integer)
        errors.add("#{attribute}[#{index}]", "must be an integer")
        next
      end
    when :boolean
      unless [true, false].include?(value)
        errors.add("#{attribute}[#{index}]", "must be a boolean")
        next
      end
    else
      errors.add("#{attribute}[#{index}]", "has an unsupported type")
      next
    end

    # Inclusion validation for non-nil values
    if inclusion_list && !inclusion_list.include?(value)
      errors.add("#{attribute}[#{index}]", "is not included in the list")
    end
  end
end

#validate_boolean(attribute) ⇒ Object



225
226
227
228
229
230
# File 'lib/api_regulator/validator.rb', line 225

def validate_boolean(attribute)
  raw_value = @raw_attributes[attribute]
  unless [true, false, "true", "false", nil].include?(raw_value)
    errors.add(attribute, "must be a boolean (true, false, or nil)")
  end
end

#validate_integer(attribute) ⇒ Object



232
233
234
235
236
237
# File 'lib/api_regulator/validator.rb', line 232

def validate_integer(attribute)
  raw_value = @raw_attributes[attribute]
  unless raw_value.to_s =~ /\A[-+]?\d+\z/ || raw_value.nil?
    errors.add(attribute, "must be an integer")
  end
end

#validate_nested_object(attribute, nested_validator_class, param) ⇒ Object



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
# File 'lib/api_regulator/validator.rb', line 200

def validate_nested_object(attribute, nested_validator_class, param)
  raw_value = @raw_attributes[attribute]

  if raw_value.nil?
    errors.add(attribute, "can't be blank") if param.required?(validation_context)
    return
  end

  unless raw_value.is_a?(Hash) || raw_value.is_a?(ActionController::Parameters)
    errors.add(attribute, "must be a hash")
    return
  end

  # Initialize the nested validator with the raw value
  validator = nested_validator_class.new(raw_value)

  # If validation fails, propagate errors
  unless validator.valid?(validation_context)
    validator.errors.each do |error|
      nested_attr = "#{attribute}.#{error.attribute}"
      errors.add(nested_attr, error.message)
    end
  end
end

#validate_string(attribute) ⇒ Object



239
240
241
242
243
244
# File 'lib/api_regulator/validator.rb', line 239

def validate_string(attribute)
  raw_value = @raw_attributes[attribute]
  unless raw_value.is_a?(String) || raw_value.nil?
    errors.add(attribute, "must be a string")
  end
end