Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate unread_comments flag (fix inconsistencies) #587

Merged
merged 14 commits into from
Jan 17, 2024
55 changes: 55 additions & 0 deletions db/migrate/20240109180000_fix_unread_comments_inconsistencies.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Fixes the unread_comments flag for all users. Unintended behavior was
# introduced in pull request #515. Migration introduced in #587.
# Behavior fixed in #585.
#
# This migration is generally *not* idempotent since users might have interacted
# with the website since the migration was run and thus they will probably have
# different unread comments flags as the ones at the time of the migration.
#
fosterfarrell9 marked this conversation as resolved.
Show resolved Hide resolved
# This migration is not reversible as we don't store the previous state of
# the unread_comments flag.
class FixUnreadCommentsInconsistencies < ActiveRecord::Migration[7.0]
def change
num_total_users = 0
num_fixed_users = 0

User.find_each do |user|
Splines marked this conversation as resolved.
Show resolved Hide resolved
was_user_fixed = fix_unread_comments_flag(user)
Splines marked this conversation as resolved.
Show resolved Hide resolved
num_fixed_users += 1 if was_user_fixed
num_total_users += 1
end

Rails.logger.debug { "Ran through #{num_total_users} users (unread comments flag)" }
Rails.logger.debug { "Fixed #{num_fixed_users} users (unread comments flag)" }
end

# Fixes the unread_comments flag for a given user.
# Returns true if the flag needed a change (and was changed), false otherwise.
def fix_unread_comments_flag(user)
readers = Reader.where(user_id: user.id)
Splines marked this conversation as resolved.
Show resolved Hide resolved
return false if readers.blank?

had_user_unread_comments = user.unread_comments
has_user_unread_comments = false

readers.each do |reader|
thread = Commontator::Thread.find_by(id: reader.thread_id)
next if thread.blank? # thread_id should never be nil, just to be sure
Splines marked this conversation as resolved.
Show resolved Hide resolved

latest_thread_comment_by_any_user = thread.comments.max_by(&:created_at)
next if latest_thread_comment_by_any_user.blank?

latest_thread_comment_time = latest_thread_comment_by_any_user.created_at
has_user_unread_comments = reader.updated_at < latest_thread_comment_time

if has_user_unread_comments
# user has unread comments, so no need to check other threads
break
end

user.update(unread_comments: has_user_unread_comments)
end

had_user_unread_comments != has_user_unread_comments
end
end
2 changes: 1 addition & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2023_11_01_100015) do
ActiveRecord::Schema[7.0].define(version: 2024_01_09_180000) do
# These are extensions that must be enabled in order to support this database
enable_extension "pgcrypto"
enable_extension "plpgsql"
Expand Down