Experiment to use dry-validation as backend for hanami-validations.
Read more at:
Experiment to use dry-validation as backend for hanami-validations.
Read more at:
| source 'https://rubygems.org' | |
| gem 'dry-validation' |
| require 'bundler/setup' | |
| require 'dry-validation' | |
| module Hanami | |
| module Validations | |
| def self.included(base) | |
| base.extend ClassMethods | |
| end | |
| module ClassMethods | |
| def self.extended(base) | |
| base.class_eval do | |
| @rules = Dry::Validation::Schema::Value.new | |
| @schema = Class.new(Dry::Validation::Schema::Form) | |
| @schema.configure {|c| c.rules = @rules.rules } | |
| end | |
| end | |
| def key(name) | |
| rules.key(name.to_sym) | |
| end | |
| def attr(name) | |
| rules.attr(name.to_sym) | |
| end | |
| def optional(name) | |
| rules.optional(name.to_sym) | |
| end | |
| def group(name, &blk) | |
| rules.key(name.to_sym).schema(&blk) | |
| end | |
| def rule(name, &blk) | |
| rules.rule(name, &blk) | |
| end | |
| def schema | |
| @schema | |
| end | |
| private | |
| def rules | |
| @rules | |
| end | |
| end | |
| def initialize(data) | |
| @data = data | |
| end | |
| def validate | |
| self.class.schema.new.call(@data) | |
| end | |
| end | |
| end | |
| class CreateJob | |
| include Hanami::Validations | |
| URL_REGEXP = URI.regexp(%w(http http)).freeze | |
| TYPES = [1, 2, 3].freeze | |
| group :job do | |
| key(:type) .required(:int?, inclusion?: TYPES) | |
| optional(:location) .maybe(:str?) | |
| optional(:remote) .maybe(:bool?) | |
| key(:title) .required(:str?, size?: 5..100) | |
| optional(:description).maybe(:str?) | |
| key(:company) .required(:str?) | |
| key(:website) .required(:str?, format?: URL_REGEXP) | |
| rule(location_required_if_not_remote: [:remote, :location]) do |remote, location| | |
| remote.false?.then(location.filled?) | |
| end | |
| end | |
| end | |
| result = CreateJob.new( | |
| job: { | |
| type: 2, # part-time | |
| remote: true, | |
| title: 'Developer', | |
| company: 'Hanami', | |
| website: 'http://hanamirb.org' | |
| } | |
| ).validate | |
| puts result.success? # => true/false | |
| puts result.messages # => Hash of errors partitioned by attribute | |
| puts result.output # => Coerced input values |