diff --git a/app/assets/javascripts/discourse/controllers/edit-category.js.es6 b/app/assets/javascripts/discourse/controllers/edit-category.js.es6
index 30006d67a31..cf30a00586a 100644
--- a/app/assets/javascripts/discourse/controllers/edit-category.js.es6
+++ b/app/assets/javascripts/discourse/controllers/edit-category.js.es6
@@ -23,6 +23,8 @@ export default Discourse.ObjectController.extend(Discourse.ModalFunctionality, {
return Discourse.Category.list().filterBy('parent_category_id', this.get('id'));
}.property('model.id'),
+ canSelectParentCategory: Em.computed.not('isUncategorizedCategory'),
+
onShow: function() {
this.changeSize();
this.titleChanged();
diff --git a/app/assets/javascripts/discourse/templates/modal/edit-category-general.js.handlebars b/app/assets/javascripts/discourse/templates/modal/edit-category-general.js.handlebars
index abdd33cf8e9..99b6acf75fb 100644
--- a/app/assets/javascripts/discourse/templates/modal/edit-category-general.js.handlebars
+++ b/app/assets/javascripts/discourse/templates/modal/edit-category-general.js.handlebars
@@ -4,17 +4,19 @@
{{text-field value=name placeholderKey="category.name_placeholder" maxlength="50"}}
-
- {{#if subCategories}}
-
- {{#each subCategories}}
- {{category-badge this}}
- {{/each}}
- {{else}}
-
- {{category-chooser valueAttribute="id" value=parent_category_id categories=parentCategories rootNone=true}}
- {{/if}}
-
+ {{#if canSelectParentCategory}}
+
+ {{#if subCategories}}
+
+ {{#each subCategories}}
+ {{category-badge this}}
+ {{/each}}
+ {{else}}
+
+ {{category-chooser valueAttribute="id" value=parent_category_id categories=parentCategories rootNone=true}}
+ {{/if}}
+
+ {{/if}}
{{#if showDescription}}
diff --git a/app/models/category.rb b/app/models/category.rb
index 509a090b49c..76d1710cf79 100644
--- a/app/models/category.rb
+++ b/app/models/category.rb
@@ -198,7 +198,8 @@ SQL
def parent_category_validator
if parent_category_id
- errors.add(:parent_category_id, I18n.t("category.errors.self_parent")) if parent_category_id == id
+ errors.add(:base, I18n.t("category.errors.self_parent")) if parent_category_id == id
+ errors.add(:base, I18n.t("category.errors.uncategorized_parent")) if uncategorized?
grandfather_id = Category.where(id: parent_category_id).pluck(:parent_category_id).first
errors.add(:base, I18n.t("category.errors.depth")) if grandfather_id
diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml
index e0e919a59bb..5330311af28 100644
--- a/config/locales/server.en.yml
+++ b/config/locales/server.en.yml
@@ -265,8 +265,9 @@ en:
replace_paragraph: "[Replace this first paragraph with a short description of your new category. This guidance will appear in the category selection area, so try to keep it below 200 characters. Until you edit this text or create topics, this category won't appear on the categories page.]"
post_template: "%{replace_paragraph}\n\nUse the following paragraphs for a longer description, as well as to establish any category guidelines or rules.\n\nSome things to consider in any discussion replies below:\n\n- What is this category for? Why should people select this category for their topic?\n\n- How is this different than the other categories we already have?\n\n- Do we need this category?\n\n- Should we merge this with another category, or split it into more categories?\n"
errors:
- self_parent: "A subcategory's parent cannot be itself."
- depth: "You can't nest a subcategory under another."
+ uncategorized_parent: "Uncategorized can't have a parent category"
+ self_parent: "A subcategory's parent cannot be itself"
+ depth: "You can't nest a subcategory under another"
trust_levels:
newuser:
title: "new user"
diff --git a/db/migrate/20140715190552_remove_uncategorized_parents.rb b/db/migrate/20140715190552_remove_uncategorized_parents.rb
new file mode 100644
index 00000000000..ebfc334277f
--- /dev/null
+++ b/db/migrate/20140715190552_remove_uncategorized_parents.rb
@@ -0,0 +1,11 @@
+class RemoveUncategorizedParents < ActiveRecord::Migration
+ def up
+ uncat = execute("SELECT value FROM site_settings WHERE name = 'uncategorized_category_id'")
+ if uncat && uncat[0] && uncat[0]['value']
+ execute "UPDATE categories SET parent_category_id = NULL where id = #{uncat[0]['value'].to_i}"
+ end
+ end
+
+ def down
+ end
+end
diff --git a/spec/models/category_spec.rb b/spec/models/category_spec.rb
index 520d383ff7b..422dbbb417c 100644
--- a/spec/models/category_spec.rb
+++ b/spec/models/category_spec.rb
@@ -116,7 +116,7 @@ describe Category do
end
it "lists all secured categories correctly" do
- uncategorized = Category.first
+ uncategorized = Category.find(SiteSetting.uncategorized_category_id)
group.add(user)
category.set_permissions(group.id => :full)
@@ -370,6 +370,19 @@ describe Category do
end
end
+ describe "uncategorized" do
+ let(:cat) { Category.where(id: SiteSetting.uncategorized_category_id).first }
+
+ it "reports as `uncategorized?`" do
+ cat.should be_uncategorized
+ end
+
+ it "cannot have a parent category" do
+ cat.parent_category_id = Fabricate(:category).id
+ cat.should_not be_valid
+ end
+ end
+
describe "parent categories" do
let(:user) { Fabricate(:user) }
let(:parent_category) { Fabricate(:category, user: user) }