Il s'agit d'un article sur la validation des colonnes Json à l'aide de json-schema dans Rails.
Cela fait longtemps que la colonne Json a été ajoutée à MySQL.
** Rails ne semble pas être la valeur par défaut, mais je veux valider Json correctement! ** ** Mais quand j'essaye de l'écrire honnêtement avec une méthode personnalisée ...
some_model.rb
class SomeModel < ApplicationRecord
validate :verify_timetable
private
def verify_timetable
errors.add(:timetable, 'Pas un tableau') && return unless timetable.is_a?(Array)
timetable.each do |el|
errors.add(:timetable, 'L'élément n'est pas un hachage') && next unless el.is_a?(Hash)
errors.add(:timetable, 'La clé de hachage n'est pas valide') && 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}La valeur de n'est pas valide")
end
end
end
end
――Ce sera un montant considérable ... ――Il est difficile de gérer des réglages fins tels que "Autorisez-vous un excès ou un manque de clés?"
Je pense que ces clients sont nombreux. Si vous n'y pensez pas, faites-vous la validation côté application?
Cette fois, j'utiliserai json-schema pour présenter la méthode de validation Json la plus cool à laquelle j'aie jamais pensé.
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
C'est assez intuitif, n'est-ce pas? Vous pouvez placer le schéma où vous le souhaitez. Je veux mettre en place la validation en validation, donc je la définis juste avant la validation.
Gemfile
gem 'json-schema'
C'est un paramètre pour pouvoir appeler avec validates: hoge, json: {schema: fuga}
.
Je l'ai mis dans ʻapp / validators`.
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
À ce stade, la validation selon le schéma Json normal (correspondance de modèle par expression régulière, définition de minLength, maxLength, etc.) est possible.
Tout en recherchant sur Google les spécifications de Json Schema, lisez Gem Readme et essayez diverses choses.
(Par exemple, strict: true
est un paramètre qui ignore le contenu requis et n'autorise pas l'excès ou le manque de clés)
C'est facile car vous pouvez écrire avec le hachage Ruby.
Il n'y a pas de type de date dans la définition de type de Json. Mais pour le moment, il existe des cas où vous souhaitez mettre des informations de date et d'heure dans Json. Ici, en référence à ce problème, le validateur de DateTime est ajouté à JSON :: Validator.
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)
Si vous avez quelque chose comme "Je veux ce format personnalisé!", Vous pouvez l'ajouter ici.
Comment était-ce? Cela semble vous libérer des descriptions de validation personnelles. Les ingénieurs qui ont négligé la validation de Json en profiteront pour améliorer la validation côté application et mener une vie Rails saine!
Recommended Posts