From 00e297a60bef91074c97c0f9a2a8da628d02bb99 Mon Sep 17 00:00:00 2001 From: Geremia Taglialatela Date: Sun, 8 Oct 2023 10:57:17 +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 --- lib/client_side_validations/active_model.rb | 19 ++++++++++++++++++- test/active_model/cases/test_validations.rb | 17 +++++++++++++++++ 2 files changed, 35 insertions(+), 1 deletion(-) 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/test/active_model/cases/test_validations.rb b/test/active_model/cases/test_validations.rb index 0e26c1b1..8600d7e9 100644 --- a/test/active_model/cases/test_validations.rb +++ b/test/active_model/cases/test_validations.rb @@ -484,6 +484,23 @@ 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, comparison: { other_than: :last_name } + end + + expected_hash = { + first_name: { + comparison: [{ + message: 'is invalid', + other_than: :last_name + }] + } + } + + 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 }