2020-05-29 17:08:35 -04:00
|
|
|
# frozen_string_literal: true
|
2020-05-30 02:08:31 -04:00
|
|
|
#
|
2020-05-29 17:08:35 -04:00
|
|
|
# JsonSchemaValidator
|
|
|
|
#
|
|
|
|
# Custom validator for json schema.
|
|
|
|
# Create a json schema within the json_schemas directory
|
|
|
|
#
|
|
|
|
# class Project < ActiveRecord::Base
|
|
|
|
# validates :data, json_schema: { filename: "file" }
|
|
|
|
# end
|
|
|
|
#
|
|
|
|
class JsonSchemaValidator < ActiveModel::EachValidator
|
2020-06-05 05:08:05 -04:00
|
|
|
FILENAME_ALLOWED = /\A[a-z0-9_-]*\Z/.freeze
|
|
|
|
FilenameError = Class.new(StandardError)
|
|
|
|
|
2020-05-29 17:08:35 -04:00
|
|
|
def initialize(options)
|
|
|
|
raise ArgumentError, "Expected 'filename' as an argument" unless options[:filename]
|
2020-06-05 05:08:05 -04:00
|
|
|
raise FilenameError, "Must be a valid 'filename'" unless options[:filename].match?(FILENAME_ALLOWED)
|
2020-05-29 17:08:35 -04:00
|
|
|
|
|
|
|
super(options)
|
|
|
|
end
|
|
|
|
|
|
|
|
def validate_each(record, attribute, value)
|
|
|
|
unless valid_schema?(value)
|
|
|
|
record.errors.add(attribute, "must be a valid json schema")
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def valid_schema?(value)
|
|
|
|
JSON::Validator.validate(schema_path, value)
|
|
|
|
end
|
|
|
|
|
|
|
|
def schema_path
|
|
|
|
Rails.root.join('app', 'validators', 'json_schemas', "#{options[:filename]}.json").to_s
|
|
|
|
end
|
|
|
|
end
|