From 7c00320733f571ed7327af07a5684fbd27833bbe Mon Sep 17 00:00:00 2001
From: ArtOfCode- <hello@artofcode.co.uk>
Date: Tue, 30 Jun 2020 15:52:40 +0100
Subject: [PATCH] Prevent loops

---
 app/assets/javascripts/tags.js |  3 ++-
 app/models/tag.rb              | 10 ++++++++++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/app/assets/javascripts/tags.js b/app/assets/javascripts/tags.js
index f8ef98d40..bbcfd7022 100644
--- a/app/assets/javascripts/tags.js
+++ b/app/assets/javascripts/tags.js
@@ -15,8 +15,9 @@ $(() => {
 
   const template = (tag) => {
     const tagSpan = `<span>${tag.text}</span>`;
+    let desc = !!tag.desc ? splitWordsMaxLength(tag.desc, 120) : '';
     const descSpan = !!tag.desc ?
-      `<br/><span class="has-color-tertiary-900 has-font-size-caption">${splitWordsMaxLength(tag.desc, 120)[0]}...</span>` :
+      `<br/><span class="has-color-tertiary-900 has-font-size-caption">${desc[0]}${desc.length > 1 ? '...' : ''}</span>` :
       '';
     return $(tagSpan + descSpan);
   }
diff --git a/app/models/tag.rb b/app/models/tag.rb
index 43436d17b..e002bf627 100644
--- a/app/models/tag.rb
+++ b/app/models/tag.rb
@@ -8,6 +8,7 @@ class Tag < ApplicationRecord
 
   validates :excerpt, length: { maximum: 600 }, allow_blank: true
   validates :wiki_markdown, length: { maximum: 30000 }, allow_blank: true
+  validate :parent_not_own_child
 
   def self.search(term)
     where('name LIKE ?', "%#{sanitize_sql_like(term)}%")
@@ -19,4 +20,13 @@ class Tag < ApplicationRecord
     query = query.gsub('$ParentId', id.to_s)
     ActiveRecord::Base.connection.execute(query).to_a.map(&:first)
   end
+
+  private
+
+  def parent_not_own_child
+    return unless parent_id.present?
+    if all_children.include? parent_id
+      errors.add(:base, "The #{parent.name} tag is already a child of this tag.")
+    end
+  end
 end
-- 
GitLab