diff --git a/app/models/topic.rb b/app/models/topic.rb
index 57acf234fb1..b23b4b82eb9 100644
--- a/app/models/topic.rb
+++ b/app/models/topic.rb
@@ -253,29 +253,8 @@ class Topic < ActiveRecord::Base
          .all
   end
 
-  def update_status(property, status, user)
-    Topic.transaction do
-
-      # Special case: if it's pinned, update that
-      if property.to_sym == :pinned
-        update_pinned(status)
-      else
-        # otherwise update the column
-        update_column(property == 'autoclosed' ? 'closed' : property, status)
-      end
-
-      key = "topic_statuses.#{property}_"
-      key << (status ? 'enabled' : 'disabled')
-
-      opts = {}
-
-      # We don't bump moderator posts except for the re-open post.
-      opts[:bump] = true if (property == 'closed' or property == 'autoclosed') and (!status)
-
-      message = property != 'autoclosed' ? I18n.t(key) : I18n.t(key, count: (((self.auto_close_at||Time.zone.now) - self.created_at) / 86_400).round )
-
-      add_moderator_post(user, message, opts)
-    end
+  def update_status(status, enabled, user)
+    TopicStatusUpdate.new(self, user).update! status, enabled
   end
 
   # Atomically creates the next post number
diff --git a/app/models/topic_status_update.rb b/app/models/topic_status_update.rb
new file mode 100644
index 00000000000..d4925b4d0eb
--- /dev/null
+++ b/app/models/topic_status_update.rb
@@ -0,0 +1,56 @@
+TopicStatusUpdate = Struct.new(:topic, :user) do
+  def update!(status, enabled)
+    status = Status.new(status, enabled)
+
+    Topic.transaction do
+      change status
+      create_moderator_post_for status
+    end
+  end
+
+  private
+
+  def change(status)
+    if status.pinned?
+      topic.update_pinned status.enabled?
+    elsif status.autoclosed?
+      topic.update_column 'closed', status.enabled?
+    else
+      topic.update_column status.name, status.enabled?
+    end
+  end
+
+  def create_moderator_post_for(status)
+    topic.add_moderator_post(user, message_for(status), options_for(status))
+  end
+
+  def message_for(status)
+    I18n.t status.locale_key, count: topic.age_in_days
+  end
+
+  def options_for(status)
+    { bump: status.reopening_topic? }
+  end
+
+  Status = Struct.new(:name, :enabled) do
+    %w(pinned autoclosed closed).each do |status|
+      define_method("#{status}?") { name == status }
+    end
+
+    def enabled?
+      enabled
+    end
+
+    def disabled?
+      !enabled?
+    end
+
+    def locale_key
+      "topic_statuses.#{name}_#{enabled? ? 'enabled' : 'disabled'}"
+    end
+
+    def reopening_topic?
+      (closed? || autoclosed?) && disabled?
+    end
+  end
+end