From 54a798eb12b5c2b9558598629bc2ecd875ef8dbf Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Mon, 27 May 2013 17:58:57 -0700 Subject: [PATCH 1/3] Add Topic#age_in_days for determining age of topic --- app/models/topic.rb | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app/models/topic.rb b/app/models/topic.rb index 5f5b8c0bddc..57acf234fb1 100644 --- a/app/models/topic.rb +++ b/app/models/topic.rb @@ -193,6 +193,10 @@ class Topic < ActiveRecord::Base @post_numbers ||= posts.order(:post_number).pluck(:post_number) end + def age_in_days + ((Time.zone.now - created_at) / 1.day).round + end + def has_meta_data_boolean?(key) meta_data_string(key) == 'true' end From be234a2bc739ea8a42d41072d2821136725c6be8 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Mon, 27 May 2013 17:59:43 -0700 Subject: [PATCH 2/3] Add test to verify autoclose moderator post --- spec/models/topic_spec.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/spec/models/topic_spec.rb b/spec/models/topic_spec.rb index 262a0064d1c..6e3819e3190 100644 --- a/spec/models/topic_spec.rb +++ b/spec/models/topic_spec.rb @@ -630,6 +630,13 @@ describe Topic do context 'autoclosed' do let(:status) { 'autoclosed' } it_should_behave_like 'a status that closes a topic' + + it 'puts the autoclose duration in the moderator post' do + @topic.created_at = 3.days.ago + @topic.update_status(status, true, @user) + + expect(@topic.posts.last.raw).to include "closed after 3 days" + end end From 21a54567ff03e52d93e8948593d825a93caf7696 Mon Sep 17 00:00:00 2001 From: Chris Hunt Date: Mon, 27 May 2013 18:00:53 -0700 Subject: [PATCH 3/3] Extract TopicStatusUpdate from Topic --- app/models/topic.rb | 25 ++------------ app/models/topic_status_update.rb | 56 +++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+), 23 deletions(-) create mode 100644 app/models/topic_status_update.rb 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