diff --git a/app/controllers/list_controller.rb b/app/controllers/list_controller.rb index 498f3ed86e1..81511387f73 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 72f5935f646..ada5d6f66d9 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 192204d189f..2651602e160 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?