From 1709dcd860ce0b6fd2ab5dc6a006c9c340a5b649 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?S=C3=A9bastien=20Gaya?= <sebastien.gaya@gmail.com>
Date: Mon, 22 Nov 2021 15:02:15 +0100
Subject: [PATCH] regenerate slug in website pages

---
 app/models/communication/website/author.rb   |  2 ++
 app/models/communication/website/category.rb |  2 +-
 app/models/communication/website/page.rb     | 12 +++++++++++-
 app/models/communication/website/post.rb     |  1 +
 4 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/app/models/communication/website/author.rb b/app/models/communication/website/author.rb
index a81414d3d..b60581dae 100644
--- a/app/models/communication/website/author.rb
+++ b/app/models/communication/website/author.rb
@@ -39,6 +39,8 @@ class Communication::Website::Author < ApplicationRecord
            class_name: 'Communication::Website::Post',
            dependent: :nullify
 
+  validates :slug, uniqueness: { scope: :communication_website_id }
+
   scope :ordered, -> { order(:last_name, :first_name) }
 
   def to_s
diff --git a/app/models/communication/website/category.rb b/app/models/communication/website/category.rb
index 5d662a5c3..3ae309ba9 100644
--- a/app/models/communication/website/category.rb
+++ b/app/models/communication/website/category.rb
@@ -57,8 +57,8 @@ class Communication::Website::Category < ApplicationRecord
                           foreign_key: 'communication_website_category_id',
                           association_foreign_key: 'communication_website_post_id'
 
-
   validates :name, presence: true
+  validates :slug, uniqueness: { scope: :communication_website_id }
 
   scope :ordered, -> { order(:position) }
 
diff --git a/app/models/communication/website/page.rb b/app/models/communication/website/page.rb
index 5e7b1f45b..2fd612957 100644
--- a/app/models/communication/website/page.rb
+++ b/app/models/communication/website/page.rb
@@ -63,8 +63,9 @@ class Communication::Website::Page < ApplicationRecord
              dependent: :nullify
 
   validates :title, presence: true
+  validates :slug, uniqueness: { scope: :communication_website_id }
 
-  before_validation :make_path
+  before_validation :regenerate_slug, :make_path
   after_save :update_children_paths if :saved_change_to_path?
 
   scope :ordered, -> { order(:position) }
@@ -92,6 +93,15 @@ class Communication::Website::Page < ApplicationRecord
 
   protected
 
+  def regenerate_slug
+    current_slug = self.slug
+    n = 0
+    while self.class.unscoped.where(communication_website_id: communication_website_id, slug: self.slug).where.not(id: id).exists?
+      n += 1
+      self.slug = [current_slug, n].join('-')
+    end
+  end
+
   def make_path
     self.path = "#{parent&.path}/#{slug}".gsub('//', '/')
   end
diff --git a/app/models/communication/website/post.rb b/app/models/communication/website/post.rb
index 51bbcec9b..b689d7c9c 100644
--- a/app/models/communication/website/post.rb
+++ b/app/models/communication/website/post.rb
@@ -53,6 +53,7 @@ class Communication::Website::Post < ApplicationRecord
   scope :recent, -> { order(published_at: :desc).limit(5) }
 
   validates :title, presence: true
+  validates :slug, uniqueness: { scope: :communication_website_id }
 
   def github_path_generated
     "_posts/#{published_at.year}/#{published_at.strftime "%Y-%m-%d"}-#{slug}.html"
-- 
GitLab