gpt4 book ai didi

ruby-on-rails - Rails 和 postgresql,在创建新记录时通知/监听

转载 作者:行者123 更新时间:2023-12-03 20:56:57 26 4
gpt4 key购买 nike

我正在根据此 tutorial 在制作服务器发送事件的上下文中试验和学习如何使用 PostgreSQL,即它的通知/监听功能。 .

教程发布NOTIFYuser channel (通过其 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]声明不是针对特定用户,而是针对整个 USER表,监听新记录(类似于... ["NOTIFY USER on INSERT", id] ?? )

澄清

抱歉不清楚。 after_save是复制错误,已更正为 after_commit以上。不过这不是问题。问题是监听器监听特定现有用户的更改,通知程序通知特定用户的更改。

相反,我想监听任何新用户的创建,并因此通知它。需要如何更改通知和监听代码才能满足此要求?

我想,与我对代码的猜测不同,通知代码可能不需要更改,因为在创建 id 时通知它似乎仍然有意义(但同样,我不知道,请随时纠正我)。但是,您如何听整张 table ,而不是特定的唱片,因为我又没有现有的唱片可听?

对于更广泛的上下文,这是原始教程中在 Controller 中的 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

但同样,就我而言,这不起作用,我没有特定的 @user我在听,我希望在创建任何用户时触发 SSE...也许是这个 Controller 代码也需要修改?但这是我非常不清楚的地方。如果我有类似...
User.on_creation do |u|
一个类方法是有道理的,但我又如何获得监听代码来监听整个表呢?

最佳答案

请使用 after_commit而不是 after_save .这样,用户记录肯定是在数据库中提交的

There are two additional callbacks that are triggered by the completion of a database transaction: after_commit and after_rollback. These callbacks are very similar to the after_save callback except that they don't execute until after database changes have either been committed or rolled back.



https://guides.rubyonrails.org/active_record_callbacks.html#transaction-callbacks

实际上它与您的问题无关,您可以使用。

以下是我将如何处理您的用例:您希望在创建用户时收到通知:

#app/models/user.rb
class User < ActiveRecord::Base
after_commit :notify_creation

def notify_creation
if id_previously_changed?
ActiveRecord::Base.connection_pool.with_connection do |connection|
self.class.execute_query(connection, ["NOTIFY user_created, '?'", id])
end
end
end

def self.on_creation
ActiveRecord::Base.connection_pool.with_connection do |connection|
begin
execute_query(connection, ["LISTEN user_created"])
connection.raw_connection.wait_for_notify do |event, pid, id|
yield self.find id
end
ensure
execute_query(connection, ["UNLISTEN user_created"])
end
end
end

def self.clean_sql(query)
sanitize_sql(query)
end

def self.execute_query(connection, query)
sql = self.clean_sql(query)
connection.execute(sql)
end
end

所以如果你使用

User.on_creation do |user|
#do something with the user
#check user.authy_status or whatever attribute you want.
end

有一件事我不确定您为什么要这样做,因为它可能会出现竞争情况,其中创建了 2 个用户,而不需要的用户首先完成。

关于ruby-on-rails - Rails 和 postgresql,在创建新记录时通知/监听,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60482660/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com