there is a table in the database with an info field json type example of an info record

{ a: '123', b: 'ABC', c: [ { x: 'abc', y: 'abc123' }, { x: 'abc', y: 'abc123' } ] } 

How can the model validate the data in info?

 info[:a] format with /\d{3}/ message = info: 'a invalid' info[:b] format with /[AZ]{3}/ message = info: 'b invalid' info[:c].map do |s| s[:x] format with /[az]{3}/ message = info: 'cx invalid' s[:y] format with /[az]{3}\d{3}/ message = info: 'cy invalid' end 

    1 answer 1

    Well, there is a whole range of options.


    First , you can describe the data form declaratively using the JSON schema . The validator will have to write independently, but its essence is simple:

     JSON::Validator.fully_validate(схема, значение) 

    ... plus throwing the results in errors .

    By writing the normal EachValidator , you can achieve a neat syntax:

     validates :info, json_schema: INFO_SCHEMA 

    True, he has error messages that are unfriendly to users, but are very friendly to developers: they show the technical essence of the error in the form of an exact message and the path in the document (keys / indexes) where the problem is found.


    Secondly , there is always a valid validate where you can arrange anything:

     validate :info_format def info_format info['c'].each_with_index |obj, i| unless obj['x'] =~ /[az]{3}/ errors.add :info, "`c`'s #{ordinalize(i+1)} element's `x` is invalid" end # ... end errors.add :info, "`a` is invalid" unless info['a'] =~ /\d{3}/ # ... end 

    Validations of such deep structures are usually useless for users, maybe it is worth using strict validation (methods with ! ), The failure of which ends with the exception of StrictValidationFailed , and not returning the object with explanations.