From 20c6bd189fbe38b1eb80a711cc70c1f028d53581 Mon Sep 17 00:00:00 2001 From: "Daniel (dB.) Doubrovkine" Date: Sun, 18 Oct 2026 11:16:48 -0400 Subject: [PATCH] Preserve localized slug history across fallbacks Fixes #184. Avoid mutating a fallback locale array and deduplicate only the explicitly selected locale history. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- CHANGELOG.md | 1 + lib/mongoid/slug.rb | 7 +++-- spec/mongoid/localized_fallback_spec.rb | 35 +++++++++++++++++++++++++ 3 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 spec/mongoid/localized_fallback_spec.rb diff --git a/CHANGELOG.md b/CHANGELOG.md index 951b6b5..6fd94b9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ## 7.1.1 (Next) +* [#184](https://github.com/mongoid/mongoid-slug/issues/184): Preserve default-locale slug history when another locale uses the same title through I18n fallbacks - [@dblock](https://github.com/dblock). * [#284](https://github.com/mongoid/mongoid-slug/pull/284): Cover saved slug mutation, suggestions, history-state reporting, require aliases and real Rails task registration; combine supported-version coverage - [@dblock](https://github.com/dblock). * Removed Code Climate badge from README - [@dblock](https://github.com/dblock). * Your contribution here. diff --git a/lib/mongoid/slug.rb b/lib/mongoid/slug.rb index 81234d3..30ab310 100644 --- a/lib/mongoid/slug.rb +++ b/lib/mongoid/slug.rb @@ -197,9 +197,6 @@ def apply_slug # to find document instead return true if new_slug.empty? - # avoid duplicate slugs - _slugs&.delete(new_slug) - if !!slug_history && _slugs.is_a?(Array) append_slug(new_slug) else @@ -284,10 +281,12 @@ def append_slug(value) # This is necessary for the scenario in which the slugged locale is not yet present # but the default locale is. In this situation, self._slugs falls back to the default # which is undesired - current_slugs = _slugs_translations.fetch(I18n.locale.to_s, []) + current_slugs = _slugs_translations.fetch(I18n.locale.to_s, []).dup + current_slugs.delete(value) current_slugs << value self._slugs_translations = _slugs_translations.merge(I18n.locale.to_s => current_slugs) else + _slugs.delete(value) _slugs << value end end diff --git a/spec/mongoid/localized_fallback_spec.rb b/spec/mongoid/localized_fallback_spec.rb new file mode 100644 index 0000000..3b2193d --- /dev/null +++ b/spec/mongoid/localized_fallback_spec.rb @@ -0,0 +1,35 @@ +# frozen_string_literal: true + +require 'spec_helper' +require 'i18n/backend/fallbacks' + +describe 'Localized slug history with fallbacks' do + around do |example| + original_fallbacks = I18n.fallbacks + I18n.fallbacks = I18n::Locale::Fallbacks.new(nl: :en) + I18n.with_locale(:en) { example.run } + ensure + I18n.fallbacks = original_fallbacks + end + + it 'preserves the default locale when adding the same title in another locale' do + page = PageSlugLocalizedHistory.create!(title: 'Shared Title') + + I18n.with_locale(:nl) { page.update!(title: 'Shared Title') } + + expect(page.reload._slugs_translations).to eq( + 'en' => ['shared-title'], 'nl' => ['shared-title'] + ) + end + + it 'keeps independent histories without duplicate current slugs' do + page = PageSlugLocalizedHistory.create!(title: 'Original Title') + I18n.with_locale(:nl) { page.update!(title: 'Original Title') } + I18n.with_locale(:nl) { page.update!(title: 'Dutch Title') } + I18n.with_locale(:nl) { page.update!(title: 'Original Title') } + + expect(page.reload._slugs_translations).to eq( + 'en' => ['original-title'], 'nl' => %w[dutch-title original-title] + ) + end +end