Difficulty creating error messages for high-level rules


#1

Hi all,

I’ve been diving into dry-validation recently and really enjoying what I’ve seen so far. But, I’ve hit a snag and can’t find the answer anywhere online or in the forums.

I’ve created a high-level rule and I’m having trouble getting a sane error message for it.

  rule(short_title_present: [:default_title, :short_title]) do |default_title, short_title|
    default_title.max_size?(30).or(short_title.filled?)
  end

I’d like to specify a single custom message for this rule, like “A short title is required when the default title is longer than 30 characters”. But I end up with this instead: “Short title present a short title is required when the default title is longer than 30 characters or short title present a short title is required when the default title is longer than 30 characters”. Woah! My message is being added for each part of the compound rule… how can I avoid this?

Here’s my config:

configure do
    def self.messages
      super.merge(
        en: {
          errors: {
            short_title_present: 'A short title is required when the default title is longer than 30 characters',
          }
        }
      )
    end
  end

Thanks for any advice,
~Alex


#2

I’ve explored further since then and fixed the doubling issue, but I’m still a bit lost as to how to nicely configure the error messages.

How are rules supposed to be named? It seems that the rule name is prepended to any error statements, so from the docs: the rule barcode_only would result in an error message like “Barcode only must be filled” which makes no sense.

Likewise, I’m having to rename my rule messages to get meaningful output. Here’s my rule:

require 'dry-validation'

ArticleForm = Dry::Validation.Form do
  required(:default_title).filled(:str?)
  required(:short_title).maybe(:str?, max_size?: 30)

  rule(short_title_present: [:default_title, :short_title]) do |default_title, short_title|
    (default_title.size?(0..30).not).then(short_title.filled?)
  end

  configure do
    def self.messages
      super.merge(
        en: {
          errors: {
            short_title_present: 'is required when the default title is longer than 30 characters'
          }
        }
      )
    end
  end

end

This gives the error “Short title present is required when the default title is longer than 30 characters” (emphasis mine). I then have to add extra config to rename my rule:

          rules: {
            short_title_present: 'short title'
          }