From 22a0956ea7ffeb23ca3da6552731ac924cc94d87 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:09:03 +0100
Subject: [PATCH] regenerate slug if needed

---
 app/models/communication/website/author.rb   |  5 +++++
 app/models/communication/website/category.rb |  3 +++
 app/models/communication/website/page.rb     | 11 +++--------
 app/models/communication/website/post.rb     |  6 ++++++
 app/models/concerns/with_slug.rb             | 17 +++++++++++++++++
 5 files changed, 34 insertions(+), 8 deletions(-)

diff --git a/app/models/communication/website/author.rb b/app/models/communication/website/author.rb
index b60581dae..b381e4d1c 100644
--- a/app/models/communication/website/author.rb
+++ b/app/models/communication/website/author.rb
@@ -59,4 +59,9 @@ class Communication::Website::Author < ApplicationRecord
     )
   end
 
+  protected
+
+  def slug_unavailable?(slug)
+    self.class.unscoped.where(communication_website_id: self.communication_website_id, slug: slug).where.not(id: self.id).exists?
+  end
 end
diff --git a/app/models/communication/website/category.rb b/app/models/communication/website/category.rb
index 3ae309ba9..9c36c1889 100644
--- a/app/models/communication/website/category.rb
+++ b/app/models/communication/website/category.rb
@@ -101,4 +101,7 @@ class Communication::Website::Category < ApplicationRecord
     end
   end
 
+  def slug_unavailable?(slug)
+    self.class.unscoped.where(communication_website_id: self.communication_website_id, slug: slug).where.not(id: self.id).exists?
+  end
 end
diff --git a/app/models/communication/website/page.rb b/app/models/communication/website/page.rb
index 2fd612957..6376ef299 100644
--- a/app/models/communication/website/page.rb
+++ b/app/models/communication/website/page.rb
@@ -65,7 +65,7 @@ class Communication::Website::Page < ApplicationRecord
   validates :title, presence: true
   validates :slug, uniqueness: { scope: :communication_website_id }
 
-  before_validation :regenerate_slug, :make_path
+  before_validation :make_path
   after_save :update_children_paths if :saved_change_to_path?
 
   scope :ordered, -> { order(:position) }
@@ -93,13 +93,8 @@ 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
+  def slug_unavailable?(slug)
+    self.class.unscoped.where(communication_website_id: self.communication_website_id, slug: slug).where.not(id: self.id).exists?
   end
 
   def make_path
diff --git a/app/models/communication/website/post.rb b/app/models/communication/website/post.rb
index b689d7c9c..532d310b0 100644
--- a/app/models/communication/website/post.rb
+++ b/app/models/communication/website/post.rb
@@ -70,4 +70,10 @@ class Communication::Website::Post < ApplicationRecord
   def to_s
     "#{title}"
   end
+
+  protected
+
+  def slug_unavailable?(slug)
+    self.class.unscoped.where(communication_website_id: self.communication_website_id, slug: slug).where.not(id: self.id).exists?
+  end
 end
diff --git a/app/models/concerns/with_slug.rb b/app/models/concerns/with_slug.rb
index c13d07f01..0f5168cb5 100644
--- a/app/models/concerns/with_slug.rb
+++ b/app/models/concerns/with_slug.rb
@@ -6,5 +6,22 @@ module WithSlug
               uniqueness: { scope: :university_id }
     validates :slug,
               format: { with: /\A[a-z0-9\-]+\z/, message: I18n.t('slug_error') }
+
+    before_validation :regenerate_slug
+
+    def regenerate_slug
+      current_slug = self.slug
+      n = 0
+      while slug_unavailable?(self.slug)
+        n += 1
+        self.slug = [current_slug, n].join('-')
+      end
+    end
+
+    protected
+
+    def slug_unavailable?(slug)
+      self.class.unscoped.where(university_id: self.university_id, slug: slug).where.not(id: self.id).exists?
+    end
   end
 end
-- 
GitLab