diff --git a/app/models/assignment.rb b/app/models/assignment.rb index 012199a..2a614db 100644 --- a/app/models/assignment.rb +++ b/app/models/assignment.rb @@ -71,11 +71,13 @@ end # target_type :string not null # active :boolean default(TRUE) # note :string +# status :text # # Indexes # # index_assignments_on_active (active) # index_assignments_on_assigned_to_id_and_assigned_to_type (assigned_to_id,assigned_to_type) # index_assignments_on_target_id_and_target_type (target_id,target_type) UNIQUE +# index_assignments_on_topic_id (topic_id) # unique_target_and_assigned (assigned_to_id,assigned_to_type,target_id,target_type) UNIQUE # diff --git a/db/migrate/20230112033741_add_topic_id_index_to_assignments.rb b/db/migrate/20230112033741_add_topic_id_index_to_assignments.rb new file mode 100644 index 0000000..ca5d17a --- /dev/null +++ b/db/migrate/20230112033741_add_topic_id_index_to_assignments.rb @@ -0,0 +1,7 @@ +# frozen_string_literal: true + +class AddTopicIdIndexToAssignments < ActiveRecord::Migration[7.0] + def change + add_index :assignments, :topic_id + end +end diff --git a/lib/assigner.rb b/lib/assigner.rb index d3bf379..0bddf59 100644 --- a/lib/assigner.rb +++ b/lib/assigner.rb @@ -213,7 +213,8 @@ class ::Assigner assign_to.is_a?(User) ? :forbidden_assign_to : :forbidden_group_assign_to when already_assigned?(assign_to, type, note, status) assign_to.is_a?(User) ? :already_assigned : :group_already_assigned - when Assignment.where(topic: topic, active: true).count >= ASSIGNMENTS_PER_TOPIC_LIMIT + when Assignment.where(topic: topic, active: true).count >= ASSIGNMENTS_PER_TOPIC_LIMIT && + !reassign? :too_many_assigns_for_topic when !can_assign_to?(assign_to) :too_many_assigns @@ -532,6 +533,11 @@ class ::Assigner false end + def reassign? + return false if !@target.is_a?(Topic) + Assignment.exists?(topic_id: @target.id, target: @target, active: true) + end + def no_assignee_change?(assignee) @target.assignment&.assigned_to_id == assignee.id end diff --git a/spec/lib/assigner_spec.rb b/spec/lib/assigner_spec.rb index 4f9b9bb..b9debb4 100644 --- a/spec/lib/assigner_spec.rb +++ b/spec/lib/assigner_spec.rb @@ -189,8 +189,11 @@ RSpec.describe Assigner do it "doesn't assign if the topic has more than 5 assignments" do other_post = nil + status = described_class.new(topic, admin).assign(Fabricate(:moderator)) + expect(status[:success]).to eq(true) + # Assign many posts to reach the limit - 1.upto(described_class::ASSIGNMENTS_PER_TOPIC_LIMIT) do + 1.upto(described_class::ASSIGNMENTS_PER_TOPIC_LIMIT - 1) do other_post = Fabricate(:post, topic: topic) user = Fabricate(:moderator) status = described_class.new(other_post, admin).assign(user) @@ -203,6 +206,10 @@ RSpec.describe Assigner do expect(status[:success]).to eq(false) expect(status[:reason]).to eq(:too_many_assigns_for_topic) + # Allows to reassign Topic + status = described_class.new(topic, admin).assign(Fabricate(:moderator)) + expect(status[:success]).to eq(true) + # Delete a post to mark the assignment as inactive PostDestroyer.new(admin, other_post).destroy