Skip to content

Instantly share code, notes, and snippets.

@nicogaldamez
Last active October 5, 2021 18:51
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nicogaldamez/2d55f5fae0ac6a4be37f3060d370afb2 to your computer and use it in GitHub Desktop.
Save nicogaldamez/2d55f5fae0ac6a4be37f3060d370afb2 to your computer and use it in GitHub Desktop.
Jsonb validator
# frozen_string_literal: true
# app/models/candidate.rb
class Candidate < ApplicationRecord
serialize :extra_details, HashSerializer
SCHEMA = {
required: ["name"],
properties: {
name: { type: "string" },
description: { type: "text" }
}
}
validates :extra_details, jsonb: { schema: SCHEMA }
end
# frozen_string_literal: true
# app/validators/json_validator.rb
class JsonbValidator < ActiveModel::EachValidator
REQUIRED_REGEX = /.+required property of '(\w+)'.+/.freeze
FRAGMENT_REGEX = /#\/(\w+)/.freeze
REQUIRED_TYPE = 'Required'.freeze
def validate_each(record, attribute, value)
return unless options.key?(:schema)
schema = options[:schema]
errors = JSON::Validator.fully_validate(schema, value, errors_as_objects: true)
return if errors.empty?
record.errors.add(attribute, format_errors(errors))
end
private
def format_errors(errors)
messages = errors.map do |error|
case error[:failed_attribute]
when REQUIRED_TYPE
format_required_error(error)
else
format_generic_error(error)
end
end.join(', ')
": #{messages}"
end
def format_required_error(error)
attr = error[:message].match(REQUIRED_REGEX).captures.first
"#{attr} es un campo requerido"
end
def format_generic_error(error)
attr = error[:fragment].match(FRAGMENT_REGEX).captures.first
"#{attr} no pudo ser guardado"
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment