Я экспериментирую и изучаю, как работать с PostgreSQL, а именно с его функцией уведомления / прослушивания, в контексте создания событий, отправляемых сервером, в соответствии с этим учебным пособием .
Учебник публикует NOTIFY
на канале user
(через его id
) каждый раз, когда сохраняется user
и изменяется атрибут authy_status
. Затем метод LISTEN
дает новый authy_status
код:
class Order < ActiveRecord::Base
after_commit :notify_creation
def notify_creation
if created?
ActiveRecord::Base.connection_pool.with_connection do |connection|
execute_query(connection, ["NOTIFY user_?, ?", id, authy_status])
end
end
end
def on_creation
ActiveRecord::Base.connection_pool.with_connection do |connection|
begin
execute_query(connection, ["LISTEN user_?", id])
connection.raw_connection.wait_for_notify do |event, pid, status|
yield status
end
ensure
execute_query(connection, ["UNLISTEN user_?", id])
end
end
end
end
Я хотел бы сделать что-то другое, но не смог найти информацию о том, как это сделать. Я хотел бы NOTIFY
, когда сначала создается пользователь (т.е. вставляется в базу данных), а затем в LISTEN
, я бы хотел yield
поднять самого созданного пользователя (или, скорее, его id
).
Как мне изменить код для достижения этой цели? Я действительно новичок в написании SQL, поэтому, например, я не очень уверен, как изменить ["NOTIFY user_?, ?", id, authy_status]
на оператор, который смотрит не на конкретного c пользователя, а на всю таблицу USER
, слушая для новых записей (что-то вроде ... ["NOTIFY USER on INSERT", id]
??)
РАЗЪЯСНЕНИЯ
Извините, что неясно. after_save
была ошибка копирования, исправленная до after_commit
выше. Это не проблема, хотя. Проблема заключается в том, что слушатель прослушивает изменения в существующем пользователе SPECIFI C, а уведомитель уведомляет об изменениях пользователя SPECIFI C.
Вместо этого я хочу прослушать любое создание нового пользователя, и поэтому сообщите об этом. Как необходимо изменить код уведомлений и прослушиваний, чтобы соответствовать этому требованию?
Полагаю, в отличие от моего предположения о коде, код уведомлений может не нуждаться в изменении, так как уведомление об идентификаторе при его создании кажется все еще имеет смысл (но опять же, я не знаю, не стесняйтесь поправлять меня). Однако как вы слушаете всю таблицу, а не конкретную запись, потому что опять же у меня нет существующей записи для прослушивания?
Для более широкого контекста, это то, как слушатель используется в SSE в контроллере из исходного урока:
def one_touch_status_live
response.headers['Content-Type'] = 'text/event-stream'
@user = User.find(session[:pre_2fa_auth_user_id])
sse = SSE.new(response.stream, event: "authy_status")
begin
@user.on_creation do |status|
if status == "approved"
session[:user_id] = @user.id
session[:pre_2fa_auth_user_id] = nil
end
sse.write({status: status})
end
rescue ClientDisconnected
ensure
sse.close
end
end
Но опять же, в моем случае, это не работает, у меня нет спецификаций c @user
Я слушаю, Я хочу, чтобы SSE срабатывал при создании любого пользователя ... Возможно, именно этот код контроллера также необходимо изменить? Но здесь мне очень непонятно. Если у меня есть что-то вроде ...
User.on_creation do |u|
Метод класса имеет смысл, но опять же, как мне получить код прослушивания для прослушивания всей таблицы?