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 |