Я думал, что каждый раз, когда пользователь редактирует чужой пост, это действие записывается в таблицу user_actions, но я только что понял, что это происходит лишь эпизодически (только для некоторых пользователей и не всегда).
Это ожидаемое поведение или есть какое-то другое условие, которое я упускаю?
Сложно дать пошаговую инструкцию для воспроизведения этой проблемы, но вот как я её обнаружил:
Выполните запрос к таблице user_actions для заданного acting_user_id (редактора), заданного user_id (редактируемого пользователя) и заданного topic_id. В моём случае:
select * from user_actions ua
where ua.acting_user_id = 229
and ua.user_id = 259
and ua.target_topic_id = 1907;
Вот что я получил:
Тип действия 2 означает, что редактируемый пользователь получил лайк от редактора.
Тип действия 6 означает, что редактор ответил редактируемому пользователю.
Я только что осознал, что либо я до конца не понимаю случаи, когда создаётся уведомление об редактировании, либо это гораздо более распространённая проблема, чем я думал.
Основные предположения
Если пользователь А редактирует то, что написал пользователь Б, происходит следующее:
В таблицу post_revisions добавляется новая строка.
В таблицу user_actions добавляется новая строка с action_type = 11.
Перейдя по адресу /u/userB/notifications/edits, пользователь Б сможет увидеть, что новое редактирование выполнил пользователь А (это зависит от user_actions).
Нажав на значок карандаша в своём посте, пользователь Б сможет увидеть само редактирование, выполненное пользователем А (это зависит от post_revisions).
Тест
Если вышеуказанные предположения верны, этот запрос должен показать все строки в таблице post_revisions для постов, созданных пользователем Б (в данном случае id 259), которые были отредактированы любым пользователем (кроме него самого или системного пользователя), вместе с соответствующими строками в user_actions для action_type = 11.
with my_user_posts as (
select
p.id,
p.user_id
from
posts p
where
p.user_id = 259 -- выберите id пользователя
)
select
up.user_id as my_user_id,
ua.user_id as target_user_id,
pr.post_id,
ua.target_post_id,
pr.user_id as editor_user_id,
ua.acting_user_id,
ua.action_type,
pr.created_at as edit_created_at,
ua.created_at as action_created_at
from
post_revisions pr
inner join my_user_posts up on up.id = pr.post_id
and up.user_id != pr.user_id -- исключим само редактирование
and pr.user_id != -1 -- исключим системные редактирования
left join user_actions ua on ua.target_post_id = pr.post_id
and ua.action_type = 11 -- только действия EDIT
order by
pr.post_id,
pr.created_at;
Ожидаемый результат
Каждая строка должна содержать как данные post_revisions, так и данные user_actions.
Фактический результат
Некоторые строки post_revisions не имеют соответствующих данных в user_actions. Следовательно, пользователь может увидеть ревизии, нажав на карандаш в каждом посте, но не получил уведомлений о нескольких редактированиях.
Добавление дополнительного редактирования к старому посту, у которого нет данных user_action. Результат: данные user_action также не появились.
Создание фейкового пользователя, копирование содержимого поста до редактирования, у которого нет данных user_action, создание с ним нового поста и применение того же редактирования, которое было выполнено другим пользователем. Результат: данные user_action появились корректно.
Повторение вышеуказанных процедур, когда пользователь активен или офлайн. Результат: изменений нет.
Повторение вышеуказанных процедур с изменением периода прощения при редактировании. Результат: изменений нет.
Выводы
Проблема, по-видимому, не является:
специфичной для пользователя. Она возникает практически у каждого пользователя.
специфичной для подключения. Тот факт, что пользователь активен или офлайн, не влияет на результат.
специфичной по времени. Изменение периода прощения при редактировании не оказало эффекта.
Проблема, по-видимому, является:
специфичной для действия. Я не видел никаких проблем с уведомлением о других действиях (LIKE, WAS_LIKED, RESPONSE, REPLY, MENTION или QUOTE). Единственная проблема касается действий EDIT.
специфичной для поста. Она возникает не у каждого поста, а только у некоторых (кажется, случайно).
Возможно, что при создании определённых постов что-то происходит, что препятствует сохранению user_actions для EDIT, но я не представляю, что это может быть.
Также возможно, что это происходит намеренно и существуют определённые условия, при которых пользователи не уведомляются о редактированиях, но я не видел этого нигде задокументированным.
Следующие шаги
Если вы знаете причину, по которой уведомления о редактировании могут не срабатывать каждый раз при редактировании, пожалуйста, сообщите об этом.
Если у вас есть собственный экземпляр Discourse, могли бы вы выполнить вышеуказанный SQL-запрос на некоторых id пользователей, чтобы проверить, видите ли вы также отсутствующие данные user_actions, и сообщить результаты?
Я просто хочу на 100% убедиться, что вы чётко понимаете, как работают периоды для редактирования, которые продолжают действовать даже в случае, если пост редактирует другой пользователь.
(Да, если пользователь A редактирует пост пользователя B, всегда создаётся принудительная ревизия редактирования. Однако это не означает, что если пользователь A отредактирует пост пользователя B 6 раз за 60 секунд, будет создано 6 ревизий и 6 уведомлений. Как видно на скриншоте выше, будет создана только одна ревизия и одно уведомление.)
Отстоят ли каждое из этих редактирований друг от друга более чем на 5 минут?
Спасибо за комментарий, Джефф. Я могу подтвердить, что да, эти правки сделаны с интервалом более 5 минут. Но даже если бы это было не так, если создается хотя бы одна запись post_revision, разве всегда не должно быть сопровождающего действия пользователя EDIT?
Кстати, я также попробовал установить период прощения для редактирования в 0, и при этом для каждого изменения создаются две идентичные записи post_revision. Не знаю, является ли это задумкой разработчиков или это несвязанный баг.
Мог бы кто-нибудь выполнить вышеуказанный запрос на своём сайте Discourse, чтобы проверить, есть ли у них post_revisions без соответствующих user_actions типа 11?
Проанализировав наш код, я полагаю, что тип user_action 11 возникает только в том случае, если вы редактируете чужой пост или каким-то иным образом вызываете уведомление об этом редактировании.
Спасибо, Сэм. Я ожидал именно этого, но на моём сайте (по крайней мере) ситуация иная. Как видно из результатов моего запроса, в некоторых случаях пользователь A редактирует пост пользователя B (что добавляет строку в post_revisions), но соответствующей строки в user_actions (с action_type 11) нет. Вот этого я не понимаю.
Я могу привести конкретный пример на хостинге, управляемом вами.
Этот пост (id 1067), созданный пользователем 3 2019-08-03 19:22 UTC, был отредактирован мной (пользователь 2) через несколько минут после создания.
Однако не было создано записи user_action типа 11 (в отличие от двух других правок, которые этот пользователь получил в тот же день для постов 1001 и 1003)
Вы можете увидеть это более наглядно, выполнив следующий запрос:
with my_user_posts as (
select
p.id,
p.user_id
from
posts p
where
p.user_id = 3 -- выберите id пользователя
)
select
up.user_id as my_user_id,
ua.user_id as target_user_id,
pr.post_id,
ua.target_post_id,
pr.user_id as editor_user_id,
ua.acting_user_id,
ua.action_type,
pr.created_at as edit_created_at,
ua.created_at as action_created_at
from
post_revisions pr
inner join my_user_posts up on up.id = pr.post_id
and up.user_id != pr.user_id -- исключая самоправки
and pr.user_id != -1 -- исключая системные правки
left join user_actions ua on ua.target_post_id = pr.post_id
and ua.action_type = 11 -- только действия EDIT
WHERE
pr.created_at between '2019-08-03' and '2019-08-04'
order by
pr.post_id,
pr.created_at
Я провёл некоторые расчёты, и в зависимости от даты от 7% до 25% правок постов (post_revisions), не являющихся самоправками, не имеют соответствующей записи user_action.
А затем я улучшил реализацию с помощью этой функции:
Существовал пограничный случай: когда пользователь ставил лайк посту другого пользователя, а затем редактировал его, уведомление об изменении не отправлялось.
Кроме того, я добавил защитный механизм, который гарантирует безусловную отправку уведомления раз в день, даже если редактирование выполнено тем же пользователем (уведомления о повторных правках от одного и того же редактора подавляются в течение одного дня). На данный момент эта настройка не конфигурируется.