Dry-validation with custom range type


#1

I am using dry-validation to perform some very simple params validations to replace rails strong_parameters and to some extent ActiveRecord validations and so far I am happy with the results.

So far the docs have been helpful but I would like some feedback if my approach is correct.

This is what I have at the moment

Dry::Validation.Params do
  required(:start_date).filled(:date?)
  required(:end_date).filled(:date?)
  rule(started_before_ended: [:start_date, :end_date]) do |start_date, end_date|
    end_date.date? > start_date.date? > end_date.gt?(value(:start_date))
  end
  validate(range_within_limit: [:start_date, :end_date]) do |start_date, end_date|
    ((start_date.to_date)..(end_date.to_date)).count <= 90
  end
end

Now I am trying to refactor the rules using custom types

class DateRange
  require 'date'
  attr_accessor :value
  def initialize(start_date:, end_date:)
    #naive implementation, is there any specific error I should raise here?
    range = (DateTime.parse(start_date))..(DateTime.parse(end_date))
    @value = range.to_a
  end

  def size
    value.size
  end
end

module Types
  include Dry::Types.module

  DateRange = Dry::Types::Definition
              .new(DateRange)
              .constructor { |input| ::DateRange.new(input) }
end

form = Dry::Validation.Params do
  configure { config.type_specs = true }
  required(:date_range, Types::DateRange).filled(max_size?: 3)

  required(:start_date).filled(:date?)
  required(:end_date).filled(:date?)
end

Is this the correct way to register a new type?
What can I improve here?


#2

So, you’re intentionally mixing together two very different concerns: white-listing and domain/business validations.

IMHO, this is a wrong way to go (and, therefore, specifics of dry-rb code are irrelevant). But if this works for you, don’t listen to me. :slight_smile: