2019-05-02 18:17:27 -04:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2017-05-11 18:23:18 -04:00
|
|
|
class TopicTimer < ActiveRecord::Base
|
2017-03-21 23:12:02 -04:00
|
|
|
include Trashable
|
2013-05-27 21:00:53 -04:00
|
|
|
|
2017-03-21 23:12:02 -04:00
|
|
|
belongs_to :user
|
|
|
|
belongs_to :topic
|
2017-04-07 05:05:58 -04:00
|
|
|
belongs_to :category
|
2013-05-27 21:00:53 -04:00
|
|
|
|
2017-03-21 23:12:02 -04:00
|
|
|
validates :user_id, presence: true
|
|
|
|
validates :topic_id, presence: true
|
|
|
|
validates :execute_at, presence: true
|
|
|
|
validates :status_type, presence: true
|
2017-05-16 14:49:42 -04:00
|
|
|
validates :status_type, uniqueness: { scope: [:topic_id, :deleted_at] }, if: :public_type?
|
|
|
|
validates :status_type, uniqueness: { scope: [:topic_id, :deleted_at, :user_id] }, if: :private_type?
|
2017-04-07 03:26:15 -04:00
|
|
|
validates :category_id, presence: true, if: :publishing_to_category?
|
|
|
|
|
2017-03-21 23:12:02 -04:00
|
|
|
validate :ensure_update_will_happen
|
|
|
|
|
2019-11-19 12:10:14 -05:00
|
|
|
scope :scheduled_bump_topics, -> { where(status_type: TopicTimer.types[:bump], deleted_at: nil).pluck(:topic_id) }
|
2019-11-19 09:24:18 -05:00
|
|
|
|
2017-03-21 23:12:02 -04:00
|
|
|
before_save do
|
|
|
|
self.created_at ||= Time.zone.now if execute_at
|
2017-05-16 14:49:42 -04:00
|
|
|
self.public_type = self.public_type?
|
2017-03-21 23:12:02 -04:00
|
|
|
|
2017-08-31 00:06:56 -04:00
|
|
|
if (will_save_change_to_execute_at? &&
|
|
|
|
!attribute_in_database(:execute_at).nil?) ||
|
|
|
|
will_save_change_to_user_id?
|
|
|
|
|
2019-05-06 21:57:55 -04:00
|
|
|
# private implementation detail have to use send
|
2017-03-21 23:12:02 -04:00
|
|
|
self.send("cancel_auto_#{self.class.types[status_type]}_job")
|
2016-05-24 14:27:48 -04:00
|
|
|
end
|
2013-05-27 21:00:53 -04:00
|
|
|
end
|
|
|
|
|
2017-03-21 23:12:02 -04:00
|
|
|
after_save do
|
2017-08-31 00:06:56 -04:00
|
|
|
if (saved_change_to_execute_at? || saved_change_to_user_id?)
|
2017-03-21 23:12:02 -04:00
|
|
|
now = Time.zone.now
|
|
|
|
time = execute_at < now ? now : execute_at
|
2013-07-03 21:47:12 -04:00
|
|
|
|
2019-05-06 21:57:55 -04:00
|
|
|
# private implementation detail have to use send
|
2017-03-21 23:12:02 -04:00
|
|
|
self.send("schedule_auto_#{self.class.types[status_type]}_job", time)
|
2013-07-03 21:47:12 -04:00
|
|
|
end
|
2013-05-27 21:00:53 -04:00
|
|
|
end
|
|
|
|
|
2017-03-21 23:12:02 -04:00
|
|
|
def self.types
|
|
|
|
@types ||= Enum.new(
|
|
|
|
close: 1,
|
2017-04-03 05:28:41 -04:00
|
|
|
open: 2,
|
2017-05-11 12:52:15 -04:00
|
|
|
publish_to_category: 3,
|
2017-05-16 14:49:42 -04:00
|
|
|
delete: 4,
|
2019-01-04 08:08:04 -05:00
|
|
|
reminder: 5,
|
2020-03-19 11:36:31 -04:00
|
|
|
bump: 6,
|
|
|
|
delete_replies: 7
|
2017-03-21 23:12:02 -04:00
|
|
|
)
|
2014-10-29 16:26:32 -04:00
|
|
|
end
|
|
|
|
|
2017-05-16 14:49:42 -04:00
|
|
|
def self.public_types
|
|
|
|
@_public_types ||= types.except(:reminder)
|
|
|
|
end
|
|
|
|
|
|
|
|
def self.private_types
|
|
|
|
@_private_types ||= types.only(:reminder)
|
|
|
|
end
|
|
|
|
|
2017-03-21 23:12:02 -04:00
|
|
|
def self.ensure_consistency!
|
2017-05-11 18:23:18 -04:00
|
|
|
TopicTimer.where("topic_timers.execute_at < ?", Time.zone.now)
|
|
|
|
.find_each do |topic_timer|
|
2017-04-13 00:02:35 -04:00
|
|
|
|
2019-05-06 21:57:55 -04:00
|
|
|
# private implementation detail scoped to class
|
2017-05-11 18:23:18 -04:00
|
|
|
topic_timer.send(
|
|
|
|
"schedule_auto_#{self.types[topic_timer.status_type]}_job",
|
|
|
|
topic_timer.execute_at
|
2017-03-21 23:12:02 -04:00
|
|
|
)
|
2013-06-06 17:04:10 -04:00
|
|
|
end
|
2013-05-27 21:00:53 -04:00
|
|
|
end
|
|
|
|
|
2017-05-16 14:49:42 -04:00
|
|
|
def public_type?
|
|
|
|
!!self.class.public_types[self.status_type]
|
|
|
|
end
|
|
|
|
|
|
|
|
def private_type?
|
|
|
|
!!self.class.private_types[self.status_type]
|
|
|
|
end
|
|
|
|
|
2017-03-21 23:12:02 -04:00
|
|
|
private
|
2013-05-27 21:00:53 -04:00
|
|
|
|
2017-03-21 23:12:02 -04:00
|
|
|
def ensure_update_will_happen
|
|
|
|
if created_at && (execute_at < created_at)
|
|
|
|
errors.add(:execute_at, I18n.t(
|
2017-05-11 18:23:18 -04:00
|
|
|
'activerecord.errors.models.topic_timer.attributes.execute_at.in_the_past'
|
2017-03-21 23:12:02 -04:00
|
|
|
))
|
2013-05-27 21:00:53 -04:00
|
|
|
end
|
2018-06-07 01:28:18 -04:00
|
|
|
end
|
2013-05-27 21:00:53 -04:00
|
|
|
|
2017-03-21 23:12:02 -04:00
|
|
|
def cancel_auto_close_job
|
2017-05-11 18:23:18 -04:00
|
|
|
Jobs.cancel_scheduled_job(:toggle_topic_closed, topic_timer_id: id)
|
2013-05-27 21:00:53 -04:00
|
|
|
end
|
2017-03-21 23:12:02 -04:00
|
|
|
alias_method :cancel_auto_open_job, :cancel_auto_close_job
|
2013-05-27 21:00:53 -04:00
|
|
|
|
2017-04-03 05:28:41 -04:00
|
|
|
def cancel_auto_publish_to_category_job
|
2017-05-11 18:23:18 -04:00
|
|
|
Jobs.cancel_scheduled_job(:publish_topic_to_category, topic_timer_id: id)
|
2017-04-03 05:28:41 -04:00
|
|
|
end
|
|
|
|
|
2017-05-11 12:52:15 -04:00
|
|
|
def cancel_auto_delete_job
|
2017-05-11 18:23:18 -04:00
|
|
|
Jobs.cancel_scheduled_job(:delete_topic, topic_timer_id: id)
|
2017-05-11 12:52:15 -04:00
|
|
|
end
|
|
|
|
|
2017-05-16 14:49:42 -04:00
|
|
|
def cancel_auto_reminder_job
|
|
|
|
Jobs.cancel_scheduled_job(:topic_reminder, topic_timer_id: id)
|
|
|
|
end
|
|
|
|
|
2019-01-04 08:08:04 -05:00
|
|
|
def cancel_auto_bump_job
|
|
|
|
Jobs.cancel_scheduled_job(:bump_topic, topic_timer_id: id)
|
|
|
|
end
|
|
|
|
|
2020-03-19 11:36:31 -04:00
|
|
|
def cancel_auto_delete_replies_job
|
|
|
|
Jobs.cancel_scheduled_job(:delete_replies, topic_timer_id: id)
|
|
|
|
end
|
|
|
|
|
|
|
|
def schedule_auto_delete_replies_job(time)
|
|
|
|
Jobs.enqueue_at(time, :delete_replies, topic_timer_id: id)
|
|
|
|
end
|
|
|
|
|
2019-01-04 08:08:04 -05:00
|
|
|
def schedule_auto_bump_job(time)
|
|
|
|
Jobs.enqueue_at(time, :bump_topic, topic_timer_id: id)
|
|
|
|
end
|
|
|
|
|
2017-03-21 23:12:02 -04:00
|
|
|
def schedule_auto_open_job(time)
|
2020-08-26 05:24:18 -04:00
|
|
|
topic.update_status('closed', true, user) if topic && !topic.closed
|
2015-07-24 16:39:03 -04:00
|
|
|
|
2017-04-03 05:28:41 -04:00
|
|
|
Jobs.enqueue_at(time, :toggle_topic_closed,
|
2017-05-11 18:23:18 -04:00
|
|
|
topic_timer_id: id,
|
2017-04-03 05:28:41 -04:00
|
|
|
state: false
|
|
|
|
)
|
2013-05-27 21:00:53 -04:00
|
|
|
end
|
|
|
|
|
2017-03-21 23:12:02 -04:00
|
|
|
def schedule_auto_close_job(time)
|
2020-08-26 04:10:13 -04:00
|
|
|
topic.update_status('closed', false, user) if topic&.closed
|
2013-07-03 16:44:45 -04:00
|
|
|
|
2017-04-03 05:28:41 -04:00
|
|
|
Jobs.enqueue_at(time, :toggle_topic_closed,
|
2017-05-11 18:23:18 -04:00
|
|
|
topic_timer_id: id,
|
2017-04-03 05:28:41 -04:00
|
|
|
state: true
|
|
|
|
)
|
|
|
|
end
|
|
|
|
|
|
|
|
def schedule_auto_publish_to_category_job(time)
|
2017-05-11 18:23:18 -04:00
|
|
|
Jobs.enqueue_at(time, :publish_topic_to_category, topic_timer_id: id)
|
2013-07-03 16:44:45 -04:00
|
|
|
end
|
2017-04-07 03:26:15 -04:00
|
|
|
|
|
|
|
def publishing_to_category?
|
2017-05-11 18:23:18 -04:00
|
|
|
self.status_type.to_i == TopicTimer.types[:publish_to_category]
|
2017-04-07 03:26:15 -04:00
|
|
|
end
|
2017-05-11 12:52:15 -04:00
|
|
|
|
|
|
|
def schedule_auto_delete_job(time)
|
2017-05-11 18:23:18 -04:00
|
|
|
Jobs.enqueue_at(time, :delete_topic, topic_timer_id: id)
|
2017-05-11 12:52:15 -04:00
|
|
|
end
|
2017-05-16 14:49:42 -04:00
|
|
|
|
|
|
|
def schedule_auto_reminder_job(time)
|
2020-09-13 21:11:55 -04:00
|
|
|
# noop, TODO(martin 2021-03-11): Remove this after timers migrated and outstanding jobs cancelled
|
2017-05-16 14:49:42 -04:00
|
|
|
end
|
2013-05-27 21:00:53 -04:00
|
|
|
end
|
2017-03-21 23:12:02 -04:00
|
|
|
|
|
|
|
# == Schema Information
|
|
|
|
#
|
2017-05-11 18:23:18 -04:00
|
|
|
# Table name: topic_timers
|
2017-03-21 23:12:02 -04:00
|
|
|
#
|
|
|
|
# id :integer not null, primary key
|
|
|
|
# execute_at :datetime not null
|
|
|
|
# status_type :integer not null
|
|
|
|
# user_id :integer not null
|
|
|
|
# topic_id :integer not null
|
|
|
|
# based_on_last_post :boolean default(FALSE), not null
|
|
|
|
# deleted_at :datetime
|
|
|
|
# deleted_by_id :integer
|
2019-01-11 14:29:56 -05:00
|
|
|
# created_at :datetime not null
|
|
|
|
# updated_at :datetime not null
|
2017-04-03 05:28:41 -04:00
|
|
|
# category_id :integer
|
2017-05-26 09:04:54 -04:00
|
|
|
# public_type :boolean default(TRUE)
|
2020-04-28 06:29:39 -04:00
|
|
|
# duration :integer
|
2017-03-21 23:12:02 -04:00
|
|
|
#
|
|
|
|
# Indexes
|
|
|
|
#
|
2018-07-16 02:18:07 -04:00
|
|
|
# idx_topic_id_public_type_deleted_at (topic_id) UNIQUE WHERE ((public_type = true) AND (deleted_at IS NULL))
|
2017-05-12 14:46:57 -04:00
|
|
|
# index_topic_timers_on_user_id (user_id)
|
2017-03-21 23:12:02 -04:00
|
|
|
#
|