From c2a360eec158e71b9a6a91b1e544af9456141dc9 Mon Sep 17 00:00:00 2001 From: Geremia Taglialatela Date: Sun, 8 Oct 2023 11:35:56 +0200 Subject: [PATCH] Fallback on "invalid" with missing translation When `config.i18n.raise_on_missing_translations` is enabled, Rails 7.1 raises on missing translation error when validation messages are not translated, which is a new behavior causing CSV to fail For unsupported validations, like `comparison`, and custom validations, like `timeliness`, CSV attempts to create a message for a key that is not present. This commit standardizes the behavior and fallbacks on "invalid" when a translation is not found, which is supposed to be the desired behavior for this use case Close #920 --- CHANGELOG.md | 4 ++++ lib/client_side_validations/active_model.rb | 19 ++++++++++++++++++- lib/client_side_validations/version.rb | 2 +- test/active_model/cases/test_validations.rb | 14 ++++++++++++++ test/base_helper.rb | 8 ++++++++ 5 files changed, 45 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 64b5887f..5eff2d03 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 22.1.1 / 2023-10-08 + +* [BUGFIX] Fix a bug with missing translations ([#920](https://github.com/DavyJonesLocker/client_side_validations/issues/920)) + ## 22.1.0 / 2023-10-05 * [FEATURE] Rails 7.1 compatibility diff --git a/lib/client_side_validations/active_model.rb b/lib/client_side_validations/active_model.rb index d927eb57..a492f6db 100644 --- a/lib/client_side_validations/active_model.rb +++ b/lib/client_side_validations/active_model.rb @@ -18,7 +18,24 @@ def copy_conditional_attributes(attribute_to, attribute_from) private def build_client_side_hash(model, attribute, options) - { message: model.errors.generate_message(attribute, message_type, options) }.merge(options.except(*callbacks_options - %i[allow_blank if unless])) + # Rails mutates `options` object when calling `model.errors.generate_message` + # by removing `message` option, if any. + # By raising on missing translations, CSV has the same behavior across + # all supported Rails versions and `config.i18n.raise_on_missing_translations` + # possible configurations. + options[:raise] = true + + message = + begin + model.errors.generate_message(attribute, message_type, options) + rescue I18n::MissingTranslationData + options[:message] = :invalid + model.errors.generate_message(attribute, message_type, options) + end + + options.delete(:raise) + + { message: message }.merge(options.except(*callbacks_options - %i[allow_blank if unless])) end def message_type diff --git a/lib/client_side_validations/version.rb b/lib/client_side_validations/version.rb index 071870d7..dc39846a 100644 --- a/lib/client_side_validations/version.rb +++ b/lib/client_side_validations/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module ClientSideValidations - VERSION = '22.1.0' + VERSION = '22.1.1' end diff --git a/test/active_model/cases/test_validations.rb b/test/active_model/cases/test_validations.rb index 0e26c1b1..8f6833eb 100644 --- a/test/active_model/cases/test_validations.rb +++ b/test/active_model/cases/test_validations.rb @@ -484,6 +484,20 @@ def test_multiple_validators_of_same_type_on_same_attribute assert_equal expected_hash, person.client_side_validation_hash end + def test_missing_translation + person = new_person do |p| + p.validates :first_name, custom_validation: true + end + + expected_hash = { + first_name: { + custom_validation: [{ message: 'is invalid' }] + } + } + + assert_equal expected_hash, person.client_side_validation_hash + end + def test_ignored_procs_validators person = new_person do |p| p.validates :first_name, format: proc { |o| o.matcher } diff --git a/test/base_helper.rb b/test/base_helper.rb index 22367f92..977f1aea 100644 --- a/test/base_helper.rb +++ b/test/base_helper.rb @@ -50,4 +50,12 @@ class Application < Rails::Application Rails.application.initialize! +class CustomValidationValidator < ActiveModel::EachValidator + def validate_each(record, attribute, value) + return if value.blank? + + record.errors.add(attribute, :invalid, **options) + end +end + module ClientSideValidations; end