FIX: Subfolder path is missing in category permalinks after slug update

FIX: Subfolder path is missing in category permalinks after slug update
diff --git a/app/models/category.rb b/app/models/category.rb
index af32b64..d7a4c0f 100644
--- a/app/models/category.rb
+++ b/app/models/category.rb
@@ -572,11 +572,9 @@ class Category < ActiveRecord::Base
   def create_category_permalink
     old_slug = saved_changes.transform_values(&:first)["slug"]
-    if self.parent_category
-      url = "c/#{self.parent_category.slug}/#{old_slug}"
-    else
-      url = "c/#{old_slug}"
-    end
+    url = +"#{Discourse.base_uri}/c"
+    url << "/#{parent_category.slug}" if parent_category_id
+    url << "/#{old_slug}"
     if Permalink.where(url: url).exists?
       Permalink.where(url: url).update_all(category_id: id)
diff --git a/spec/models/category_spec.rb b/spec/models/category_spec.rb
index 89a6621..2406c25 100644
--- a/spec/models/category_spec.rb
+++ b/spec/models/category_spec.rb
@@ -332,6 +332,15 @@ describe Category do
       expect(Permalink.count).to eq(0)
+    it "correctly creates permalink when category slug is changed in subfolder install" do
+      GlobalSetting.stubs(:relative_url_root).returns('/forum')
+      Discourse.stubs(:base_uri).returns("/forum")
+      old_url = @category.url
+      @category.update_attributes(slug: 'new-category')
+      permalink = Permalink.last
+      expect(permalink.url).to eq(old_url[1..-1])
+    end
     it "should not set its description topic to auto-close" do
       category = Fabricate(:category, name: 'Closing Topics', auto_close_hours: 1)
       expect(category.topic.public_topic_timer).to eq(nil)

sha: 2909e7fb

This commit has been mentioned on Discourse Meta. There might be relevant details there:

Thanks. I suspect there may be more cases of this, what about topic renames?

While updating a topic’s title it won’t create any permalink redirection. Instead topic_id in the URL will be used to navigate to the correct topic.

1 Like

Ah ok, all good then :wink:

Why do we need + in front of the string?

1 Like

Very good habit, the + means the string is not frozen even if frozen string literal is enabled on the file

Sometime soon it will be enabled on all our files