require 'dry-validation' SCHEMA = Dry::Validation.Schema do configure do config.input_processor = :sanitizer def self.messages Dry::Validation::Messages.default.merge(en: { errors: { unique?: "oops not unique" }}) end def unique?(value) value.flat_map { |kp| kp[:key_phrase] }.uniq.size == value.size end end required(:key_phrases).each do schema do required(:weight).filled(gteq?: 0, lteq?: 4) required(:key_phrase).filled end end rule(unique_phrases: [:key_phrases]) do |key_phrases| key_phrases.unique? end end module JsonPayload def self.example_repeated_keys { name: "name", user_id: "01dd7006-8b96-48e8-954e-5a9da4cd72e0", bap_control_id: "01dd7006-8b96-48e8-954e-5a9da4cd72e0", implementation: "imp lang", key_phrases: [ { key_phrase: "ph1", weight: 5.3 }, { key_phrase: "ph1", weight: 6.2 } ] } end def self.example_normal { name: "name", user_id: "01dd7006-8b96-48e8-954e-5a9da4cd72e0", bap_control_id: "01dd7006-8b96-48e8-954e-5a9da4cd72e0", implementation: "imp lang", key_phrases: [ { key_phrase: "ph1", weight: 5.3 }, { key_phrase: "ph2", weight: 6.2 } ] } end end puts SCHEMA.(JsonPayload.example_normal).messages.inspect puts SCHEMA.(JsonPayload.example_repeated_keys).messages.inspect