From 44308d07366daa62b315fe1dfd5136e24a00c67d Mon Sep 17 00:00:00 2001
From: ArtOfCode- <hello@artofcode.co.uk>
Date: Fri, 8 May 2020 19:58:28 +0100
Subject: [PATCH] Add tag ordering

---
 app/models/application_record.rb   | 7 +++++++
 app/models/tag.rb                  | 7 +++++++
 app/views/posts/_expanded.html.erb | 8 +++++---
 app/views/posts/_list.html.erb     | 8 +++++---
 4 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/app/models/application_record.rb b/app/models/application_record.rb
index e5c54e276..2aa76e8e6 100644
--- a/app/models/application_record.rb
+++ b/app/models/application_record.rb
@@ -30,6 +30,13 @@ class ApplicationRecord < ActiveRecord::Base
 
     ActiveRecord::Base.send(:sanitize_sql_array, ["MATCH (#{cols}) AGAINST (? IN BOOLEAN MODE)", term])
   end
+
+  def self.sanitize_sql_in(ary)
+    return "(NULL)" unless ary.present? && ary.respond_to?(:map)
+
+    ary = ary.map { |el| ActiveRecord::Base.sanitize_sql_array(['?', el]) }
+    "(#{ary.join(', ')})"
+  end
 end
 
 module UserSortable
diff --git a/app/models/tag.rb b/app/models/tag.rb
index 65024e43b..cd89a7d0d 100644
--- a/app/models/tag.rb
+++ b/app/models/tag.rb
@@ -1,6 +1,13 @@
 class Tag < ApplicationRecord
   include CommunityRelated
 
+  scope :category_order, -> (required_ids, topic_ids) do
+    helpers = ActionController::Base.helpers
+    order(Arel.sql("id IN #{sanitize_sql_in(required_ids)} DESC"),
+          Arel.sql("id IN #{sanitize_sql_in(topic_ids)} DESC"),
+          name: :asc)
+  end
+
   has_and_belongs_to_many :posts
   belongs_to :tag_set
 
diff --git a/app/views/posts/_expanded.html.erb b/app/views/posts/_expanded.html.erb
index b00c2ca01..a2b45b809 100644
--- a/app/views/posts/_expanded.html.erb
+++ b/app/views/posts/_expanded.html.erb
@@ -98,10 +98,12 @@
           <% if is_question %>
             <div class="post--tags has-padding-2">
               <% tag_set = post.tag_set %>
-              <% post.tags.each do |tag| %>
+              <% required_ids = post.category&.required_tag_ids %>
+              <% topic_ids = post.category&.topic_tag_ids %>
+              <% post.tags.category_order(required_ids, topic_ids).each do |tag| %>
                 <% next if tag.nil? %>
-                <% required = post.category&.required_tag_ids&.include? tag.id %>
-                <% topic = post.category&.topic_tag_ids&.include? tag.id %>
+                <% required = required_ids&.include? tag.id %>
+                <% topic = topic_ids&.include? tag.id %>
                 <%= link_to tag.name, questions_tagged_path(tag_set: tag_set.id, tag: tag.name),
                             class: "badge is-tag #{required ? 'is-filled' : ''} #{topic ? 'is-outlined' : ''}" %>
               <% end %>
diff --git a/app/views/posts/_list.html.erb b/app/views/posts/_list.html.erb
index 557282947..5703b4e84 100644
--- a/app/views/posts/_list.html.erb
+++ b/app/views/posts/_list.html.erb
@@ -27,9 +27,11 @@
     <div class="has-padding-top-2">
       <% if is_question %>
         <% tag_set = post.tag_set %>
-        <% post.tags.each do |tag| %>
-          <% required = post.category&.required_tag_ids&.include? tag.id %>
-          <% topic = post.category&.topic_tag_ids&.include? tag.id %>
+        <% required_ids = post.category&.required_tag_ids %>
+        <% topic_ids = post.category&.topic_tag_ids %>
+        <% post.tags.category_order(required_ids, topic_ids).each do |tag| %>
+          <% required = required_ids&.include? tag.id %>
+          <% topic = topic_ids&.include? tag.id %>
           <%= link_to tag.name, questions_tagged_path(tag_set: tag_set.id, tag: tag.name),
                       class: "badge is-tag #{required ? 'is-filled' : ''} #{topic ? 'is-outlined' : ''}" %>
         <% end %>
-- 
GitLab