diff --git a/app/controllers/item_categories_controller.rb b/app/controllers/item_categories_controller.rb
index 3d291e76ab..20a336a958 100644
--- a/app/controllers/item_categories_controller.rb
+++ b/app/controllers/item_categories_controller.rb
@@ -33,6 +33,17 @@ def update
end
end
+ def destroy
+ @item_category = current_organization.item_categories.find_by(id: params[:id])
+ if @item_category.items.exists?
+ flash[:alert] = "Cannot delete item category because it has associated items."
+ else
+ @item_category.destroy
+ flash[:notice] = "#{@item_category.name} has been deleted."
+ end
+ redirect_to items_path
+ end
+
private
def item_category_params
diff --git a/app/models/item_category.rb b/app/models/item_category.rb
index 20c2fab014..4d774225c2 100644
--- a/app/models/item_category.rb
+++ b/app/models/item_category.rb
@@ -16,5 +16,16 @@ class ItemCategory < ApplicationRecord
belongs_to :organization
has_many :items, -> { order(name: :asc) }, inverse_of: :item_category, dependent: :nullify
- has_many :partner_groups, dependent: :nullify
+ has_and_belongs_to_many :partner_groups, dependent: :nullify
+
+ before_destroy :ensure_no_associated_partner_groups
+
+ private
+
+ def ensure_no_associated_partner_groups
+ if partner_groups.exists?
+ errors.add(:base, "Cannot delete item category with associated partner groups")
+ throw(:abort)
+ end
+ end
end
diff --git a/app/views/items/_item_categories.html.erb b/app/views/items/_item_categories.html.erb
index 12554cd444..a4115a3c3f 100644
--- a/app/views/items/_item_categories.html.erb
+++ b/app/views/items/_item_categories.html.erb
@@ -27,9 +27,10 @@
<% end %>
-
+ |
<%= view_button_to item_category_path(item_category) %>
<%= edit_button_to edit_item_category_path(item_category.id) %>
+ <%= delete_button_to(item_category_path(item_category.id), { confirm: confirm_delete_msg(item_category.name) }) if (item_category.items.count <= 0) %>
|
<% end %>
diff --git a/db/schema.rb b/db/schema.rb
index 25c73f88a0..47766f8cb8 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -324,7 +324,7 @@
t.bigint "old_partner_id"
t.boolean "archived", default: false
t.index ["partner_id"], name: "index_families_on_partner_id"
- end
+ end
create_table "flipper_features", force: :cascade do |t|
t.string "key", null: false
diff --git a/spec/models/item_category_spec.rb b/spec/models/item_category_spec.rb
index df1eb14501..7eb6bc1785 100644
--- a/spec/models/item_category_spec.rb
+++ b/spec/models/item_category_spec.rb
@@ -28,4 +28,24 @@
describe "versioning" do
it { is_expected.to be_versioned }
end
+
+ describe "delete" do
+ let(:item_category) { create(:item_category) }
+ let(:partner_group) { create(:partner_group, item_categories: [item_category]) }
+
+ before do
+ partner_group
+ end
+
+ it "should not delete if associated with partner groups" do
+ expect(item_category.partner_groups).not_to be_empty
+ expect { item_category.destroy }.not_to change(ItemCategory, :count)
+ expect(item_category.errors.full_messages).to include("Cannot delete item category with associated partner groups")
+ end
+
+ it "should delete if not associated with partner groups" do
+ item_category.partner_groups.destroy_all
+ expect { item_category.destroy }.to change(ItemCategory, :count).by(-1)
+ end
+ end
end
diff --git a/spec/requests/item_categories_requests_spec.rb b/spec/requests/item_categories_requests_spec.rb
index 24f4b69fbb..fa75c17f3b 100644
--- a/spec/requests/item_categories_requests_spec.rb
+++ b/spec/requests/item_categories_requests_spec.rb
@@ -93,4 +93,29 @@
end
end
end
+
+ describe "DELETE #destroy" do
+ let!(:item_category) { create(:item_category, organization: organization) }
+
+ context "when the item category has no associated items" do
+ it "destroys the requested item category" do
+ expect {
+ delete item_category_url(id: item_category.id)
+ }.to change(ItemCategory, :count).by(-1)
+ expect(response).to redirect_to(items_path)
+ end
+ end
+
+ context "when the item category has associated items" do
+ let!(:item) { create(:item, item_category: item_category) }
+
+ it "does not destroy the item category and shows an error" do
+ expect {
+ delete item_category_url(id: item_category.id)
+ }.not_to change(ItemCategory, :count)
+ expect(response).to redirect_to(items_path)
+ expect(flash[:alert]).to eq("Cannot delete item category because it has associated items.")
+ end
+ end
+ end
end