These are chat archives for dry-rb/chat

4th
Mar 2017
Eduardo de Oliveira Hernandes
@eduardodeoh
Mar 04 2017 01:45
Hey guys, i need some help about how to create a custom error message with a custom predicate, something like https://github.com/dry-rb/dry-validation/blob/master/config/errors.yml#L30
def self.messages
        super.merge( en: { errors: { control_exists?: "associated Control %{name_of_control}  not found!" } } )
 end
I see the docs here - http://dry-rb.org/gems/dry-validation/error-messages/ - but i didn’t find any example like my problem. Any help?
Gustavo Caso
@GustavoCaso
Mar 04 2017 08:52
Hey @eduardodeoh
I do not have much experience with the library, but couldn't you configure the yml for each schema, or update the one you are using adding control_exists? key
Gustavo Caso
@GustavoCaso
Mar 04 2017 09:43
@eduardodeoh I had play a little in the console and came up with this solution hope that it helps, and please correct me if I'm wrong with the implementation
require 'dry-validation'
require 'dry/logic'
require 'dry/logic/predicates'

module CustomPredicates
  include Dry::Logic::Predicates

  def self.control_exists?(input)
    input.key?(:control_exists)
  end
end

schema = Dry::Validation.Schema do
  configure do
    predicates(CustomPredicates)
    config.messages_file = Pathname(__dir__).join('examples/custom_error_file.yml').realpath.freeze
  end

  required(:db) { filled? & control_exists? }
end

schema.call({}).messages
# {:db=>["is missing", "associated Control key not found in !"]}

schema.call(db: { control_exists: 'NYC' }).messages
# {}

schema.call(db: { hello: 'NYC' }).messages
# {:db=>["associated Control key not found in {:hello=>\"NYC\"}!"]}
the messages files looks like this
en:
  errors:
    control_exists?: "associated Control key not found in %{input}!"
Sergey Kukunin
@Kukunin
Mar 04 2017 12:52
don't you think we need permissive_with_defaults constructor_type for dry-struct?
in case I don't want to specify keys, if they're optional, and still permissive behaviour
Piotr Solnica
@solnic
Mar 04 2017 16:49
@Kukunin we could add it if you have a use case
Sergey Kukunin
@Kukunin
Mar 04 2017 17:16
described in github issue
Minh Quy
@MQuy
Mar 04 2017 20:04

hi, i wonder how can i overcome this problem

class User < Dry::Struct
  attribute :name, Types::String.optional
  attribute :age, Types::Coercible::Int
end

then

User.new(age: 1)  # => :name is missing in Hash input
Piotr Solnica
@solnic
Mar 04 2017 20:08
@MQuy constructor_type :schema (this sets the underlying hash constructor, you can read about different types and their behavior right here)
Minh Quy
@MQuy
Mar 04 2017 20:10
@solnic thank you so much :bow:
Eduardo de Oliveira Hernandes
@eduardodeoh
Mar 04 2017 20:12
@GustavoCaso thanks, your example helped me to resolve the problem :clap:
Gustavo Caso
@GustavoCaso
Mar 04 2017 20:23
Great to hear @eduardodeoh
Minh Quy
@MQuy
Mar 04 2017 20:25

quite new for me, i wonder that how can i make something like this work

class UserEntity < Dry::Struct
  constructor_type : schema

  attribute :email, Types::Strict::String
  attribute :encrypted_password, Types::Strict::String
  attribute :full_name, Types::Strict::String.optional
end

It will raise error if it is missed email or encrypted_password, but will be ok for missing full_name :d

Piotr Solnica
@solnic
Mar 04 2017 20:29
it should raise if email or password are not strings
Minh Quy
@MQuy
Mar 04 2017 20:30
yup, but is it possible for the case that it raises for missing email or encrypted_password and doesn't raise for missing full_name
assume that we pass correct type for email and encrypted_password
Piotr Solnica
@solnic
Mar 04 2017 20:32
missing as in missing key in attributes?
Minh Quy
@MQuy
Mar 04 2017 20:33
yup like
UserEntity.new(email: 'xx', encrypted_password: '') # => ok
UserEntity.new(email: 'xx') #=> error due to missing encrypted_password
email, encrypted_password is required
full_name is optional
Piotr Solnica
@solnic
Mar 04 2017 20:35
it will raise if there’s no encrypted_password
Minh Quy
@MQuy
Mar 04 2017 20:36
it raises for full_name but in this case full_name is optional
Piotr Solnica
@solnic
Mar 04 2017 20:38
@MQuy hmm no it doesn't
Minh Quy
@MQuy
Mar 04 2017 20:39
@solnic it won't raise if i use schema constructor type
also, won't raise if it is missed encrypted_password
sorry for the bad explaination
Piotr Solnica
@solnic
Mar 04 2017 20:41
pls gist what you’re trying to do, because it should raise since you defined strict strings
Piotr Solnica
@solnic
Mar 04 2017 22:11
@MQuy you need constructor_type :schema because by default structs expect all keys to be present in the attributes hash