These are chat archives for dry-rb/chat

20th
Apr 2018
Jonah
@jonahx
Apr 20 2018 12:27

I want a type to represent a non empty string, is there a builtin for this or should I just do:

NonEmptyString = Types::Strict::String.constrained(
  format: /\S+/
)

?

Nikita Shilnikov
@flash-gordon
Apr 20 2018 12:36
there's no predefined type for this
Daniel Sandbecker
@daniels
Apr 20 2018 13:38

In Dry::Validation, is there a way to define a custom error message for a rule block, that isn't composed of messages from the individual predicates used in the block? I have a form where I want to enforce a checkbox only if the birthdate given in another field is for a person under 18:

rule(acknowledge_age_if_young: [:acknowledge_age, :birth_date]) do |acknowledge_age, birth_date|
  birth_date.older?(18) | acknowledge_age.true?
end

But the automatic error message is a join of the older?-message and the true?-message, with " or " as the delimiter: "must be older than 18 or must be true". I can customize each of these messages, but I don't see how/if I can use a message without an " or ". Basically I just wan't to say "You need to check this box if you're not 18".

Daniel Sandbecker
@daniels
Apr 20 2018 14:20
Ok, after searching and testing for hours I found an answer in the forum right after I posted here: https://discourse.dry-rb.org/t/difficulty-creating-error-messages-for-high-level-rules/238/2
Jonah
@jonahx
Apr 20 2018 14:53

Could someone clarify for me the purpose of Types.Constructor:

user_type = Types.Constructor(User)

# It is equivalent to User.new(name: 'John')
user_type[name: 'John’]

What is the differentce between User and user_type — other than that you can construct with []rather than new? Types.Instance makes sense to me, since we’re checking that the value passed is an instance of a certain class. But what are we checking with a constructor type?

Piotr Solnica
@solnic
Apr 20 2018 16:06
@jonahx just a shortcut for Types::Definition.new(User).constructor(&User.method(:new))
Jonah
@jonahx
Apr 20 2018 16:07
@solnic what is the typical use case for this kind of type?
Piotr Solnica
@solnic
Apr 20 2018 16:10
@jonahx ie type annotation in dry/rom structs
in general, dry-types provide type definitions (as in, they define the primitive class), with optional constructors, constraints and arbitrary meta-information, there are tons of use cases for them
Jonah
@jonahx
Apr 20 2018 16:14
@solnic thanks, yeah, i knew that part. i use and love Dry::Struct. By use case I meant, an example of a dry struct that would need an attribute with a contructor type. I’m having trouble connecting the idea to something that would come up in my work.
Jonah
@jonahx
Apr 20 2018 17:37

separate question: Is there a better (more concise) way to achieve the equivalent of the following using dry::struct or dry::types:

class Webservices
  include Enumerable
  extend Forwardable

  TYPE = Types.Array(Types.Instance(Webservice))

  def initialize(arr)
    @arr = TYPE[arr]
  end
  def_delegators :@arr, :each
end

Note: I want to be able to construct using a single, unnamed parameter as in Webservices.new([service1, service2]).
Essentially, I want a typed array constructible using Webservices.new.