discourse/app/models/topic_group.rb

87 lines
2.7 KiB
Ruby

# frozen_string_literal: true
class TopicGroup < ActiveRecord::Base
belongs_to :group
belongs_to :topic
def self.update_last_read(user, topic_id, post_number)
updated_groups = update_read_count(user, topic_id, post_number)
create_topic_group(user, topic_id, post_number, updated_groups.map(&:group_id))
TopicTrackingState.publish_read_indicator_on_read(topic_id, post_number, user.id)
end
def self.new_message_update(user, topic_id, post_number)
updated_groups = update_read_count(user, topic_id, post_number)
create_topic_group(user, topic_id, post_number, updated_groups.map(&:group_id))
TopicTrackingState.publish_read_indicator_on_write(topic_id, post_number, user.id)
end
def self.update_read_count(user, topic_id, post_number)
update_query = <<~SQL
UPDATE topic_groups tg
SET
last_read_post_number = GREATEST(:post_number, tg.last_read_post_number),
updated_at = :now
FROM topic_allowed_groups tag
INNER JOIN group_users gu ON gu.group_id = tag.group_id
WHERE gu.user_id = :user_id
AND tag.topic_id = :topic_id
AND tg.topic_id = :topic_id
RETURNING
tg.group_id
SQL
updated_groups =
DB.query(
update_query,
user_id: user.id,
topic_id: topic_id,
post_number: post_number,
now: DateTime.now,
)
end
def self.create_topic_group(user, topic_id, post_number, updated_group_ids)
query = <<~SQL
INSERT INTO topic_groups (topic_id, group_id, last_read_post_number, created_at, updated_at)
SELECT tag.topic_id, tag.group_id, :post_number, :now, :now
FROM topic_allowed_groups tag
INNER JOIN group_users gu ON gu.group_id = tag.group_id
WHERE gu.user_id = :user_id
AND tag.topic_id = :topic_id
SQL
query += "AND NOT(tag.group_id IN (:already_updated_groups))" if updated_group_ids.present?
query += <<~SQL
ON CONFLICT(topic_id, group_id)
DO UPDATE SET last_read_post_number = :post_number, created_at = :now, updated_at = :now
SQL
DB.exec(
query,
user_id: user.id,
topic_id: topic_id,
post_number: post_number,
now: DateTime.now,
already_updated_groups: updated_group_ids,
)
end
end
# == Schema Information
#
# Table name: topic_groups
#
# id :bigint not null, primary key
# group_id :integer not null
# topic_id :integer not null
# last_read_post_number :integer default(0), not null
# created_at :datetime not null
# updated_at :datetime not null
#
# Indexes
#
# index_topic_groups_on_group_id_and_topic_id (group_id,topic_id) UNIQUE
#