FIX: Handle sub-sub-category paths without an id

FIX: Handle sub-sub-category paths without an id

diff --git a/app/controllers/list_controller.rb b/app/controllers/list_controller.rb
index 498f3ed..8151138 100644
--- a/app/controllers/list_controller.rb
+++ b/app/controllers/list_controller.rb
@@ -319,9 +319,7 @@ class ListController < ApplicationController
     if id.present?
       @category = Category.find_by_id(id)
     elsif slug_path.present?
-      if (1..2).include?(slug_path.size)
-        @category = Category.find_by_slug(*slug_path.reverse)
-      end
+      @category = Category.find_by_slug_path(slug_path)
 
       # Legacy paths
       if @category.nil? && parts.last =~ /\A\d+-category/
diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb
index 72f5935..ada5d6f 100644
--- a/app/controllers/tags_controller.rb
+++ b/app/controllers/tags_controller.rb
@@ -359,9 +359,7 @@ class TagsController < ::ApplicationController
       if id.present?
         @filter_on_category = Category.find_by_id(id)
       elsif slug_path.present?
-        if (1..2).include?(slug_path.size)
-          @filter_on_category = Category.find_by_slug(*slug_path.reverse)
-        end
+        @filter_on_category = Category.find_by_slug_path(slug_path)
 
         # Legacy paths
         if @filter_on_category.nil? && parts.last =~ /\A\d+-category/
diff --git a/app/models/category.rb b/app/models/category.rb
index 192204d..2651602 100644
--- a/app/models/category.rb
+++ b/app/models/category.rb
@@ -777,22 +777,29 @@ class Category < ActiveRecord::Base
     end
   end
 
-  def self.find_by_slug(category_slug, parent_category_slug = nil)
-
-    return nil if category_slug.nil?
+  def self.find_by_slug_path(slug_path)
+    return nil if slug_path.empty?
+    return nil if slug_path.size > SiteSetting.max_category_nesting
 
     if SiteSetting.slug_generation_method == "encoded"
-      parent_category_slug = CGI.escape(parent_category_slug) unless parent_category_slug.nil?
-      category_slug = CGI.escape(category_slug)
+      slug_path.map! { |slug| CGI.escape(slug) }
     end
 
-    if parent_category_slug
-      parent_category_id = self.where(slug: parent_category_slug, parent_category_id: nil).select(:id)
+    query =
+      slug_path.inject(nil) do |parent_id, slug|
+        Category.where(
+          slug: slug,
+          parent_category_id: parent_id,
+        ).select(:id)
+      end
 
-      self.where(slug: category_slug, parent_category_id: parent_category_id).first
-    else
-      self.where(slug: category_slug, parent_category_id: nil).first
-    end
+    Category.find_by_id(query)
+  end
+
+  def self.find_by_slug(category_slug, parent_category_slug = nil)
+    return nil if category_slug.nil?
+
+    find_by_slug_path([parent_category_slug, category_slug].compact)
   end
 
   def subcategory_list_includes_topics?

GitHub sha: c8fed90e