Dies ist ein Artikel über die Validierung von Json-Spalten mithilfe von json-schema in Rails.
Es ist lange her, dass die Json-Spalte zu MySQL hinzugefügt wurde.
** Rails scheint nicht die Standardeinstellung zu sein, aber ich möchte Json ordnungsgemäß validieren! ** ** ** Aber wenn ich versuche, es ehrlich mit einer benutzerdefinierten Methode zu schreiben ...
some_model.rb
class SomeModel < ApplicationRecord
validate :verify_timetable
private
def verify_timetable
errors.add(:timetable, 'Kein Array') && return unless timetable.is_a?(Array)
timetable.each do |el|
errors.add(:timetable, 'Element ist kein Hash') && next unless el.is_a?(Hash)
errors.add(:timetable, 'Hash-Schlüssel ist ungültig') && next unless el.keys.sort == %w[end_at start_at]
%w[start_at end_at].each do |key|
DateTime.parse(el[key])
rescue ArgumentError
errors.add(:timetable, "#{key}Der Wert von ist ungültig")
end
end
end
end
――Es wird eine beträchtliche Menge sein ... ――Es ist schwierig, eine Feinabstimmung durchzuführen, z. B. "Erlauben Sie einen Über- oder Mangel an Tasten?"
Ich denke, es gibt viele solcher Kunden. Wenn Sie nicht darüber nachdenken, führen Sie die Validierung auf der Anwendungsseite durch?
Dieses Mal werde ich json-schema verwenden, um die coolste Json-Validierungsmethode vorzustellen, an die ich je gedacht habe.
some_model.rb
class SomeModel < ApplicationRecord
TIMETABLE_SCHEMA = {
type: 'array',
items: {
type: 'object',
properties: {
start_at: { type: 'string', format: :datetime },
end_at: { type: 'string', format: :datetime },
},
},
}.freeze
validates :timetable, json: { schema: TIMETABLE_SCHEMA }
end
Es ist ziemlich intuitiv, nicht wahr? Sie können das Schema an einer beliebigen Stelle platzieren. Ich möchte die Validierung in der Validierung zusammenstellen, daher definiere ich sie kurz vor der Validierung.
Gemfile
gem 'json-schema'
Es ist eine Einstellung, um mit validates: hoge, json: {schema: fuga}
aufrufen zu können.
Ich habe es in "App / Validatoren" eingefügt.
app/validators/json_validator.rb
class JsonValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
JSON::Validator.validate!(options[:schema], value, strict: true)
rescue JSON::Schema::ValidationError => e
record.errors[attribute] << (options[:message] || e.message)
end
end
Zu diesem Zeitpunkt ist eine Validierung gemäß dem normalen Json-Schema (Mustervergleich durch regulären Ausdruck, Definition von minLength, maxLength usw.) möglich. Lesen Sie Gem Readme und probieren Sie verschiedene Dinge aus, während Sie die Spezifikationen von Json Schema googeln. (Zum Beispiel ist "strict: true" eine Einstellung, die den erforderlichen Inhalt ignoriert und keinen Über- oder Mangel an Schlüsseln zulässt.) Es ist einfach, weil Sie mit Ruby-Hash schreiben können.
In Jsons Typdefinition gibt es keinen Datumstyp. Derzeit gibt es jedoch Fälle, in denen Sie Datums- und Uhrzeitinformationen in Json einfügen möchten. Unter Bezugnahme auf dieses Problem wird der Validator für DateTime zu JSON :: Validator hinzugefügt.
config/initializers/json_validator.rb
datetime = -> value {
begin
DateTime.parse(value)
rescue ArgumentError
raise JSON::Schema::CustomFormatError.new('not datetime format')
end
}
JSON::Validator.register_format_validator(:datetime, datetime)
Wenn Sie etwas wie "Ich möchte dieses benutzerdefinierte Format!" Haben, können Sie es hier hinzufügen.
Wie war es? Dies scheint Sie von persönlichen Validierungsbeschreibungen zu befreien. Ingenieure, die die Validierung von Json vernachlässigt haben, werden diese Gelegenheit nutzen, um die Validierung auf der Anwendungsseite zu verbessern und ein gesundes Rails-Leben zu führen!
Recommended Posts