我有一个Appointment
模型,我想在每次创建或更新约会时将广播发送到前端应用程序以作为响应。这是我模型的代码。
class Appointment < ApplicationRecord
belongs_to :tutor, class_name: 'User'
belongs_to :student, class_name: 'User'
after_create :appointment_notification
after_update :appointment_notification
def appointment_notification
Notification.create(
from: student,
to: tutor,
name: :student_create_appointment, # here you can detect any type
model: :appointment
)
end
end
和Notification
模型和表格来保存所有通知的历史记录
class Notification < ApplicationRecord
belongs_to :from, class_name: 'User', foreign_key: :from_id
belongs_to :to, class_name: 'User', foreign_key: :to_id
before_create :set_seen
after_create :push_notification
def set_seen
self.seen = false
end
def push_notification
if to.user_push_notification.respond_to?(name) &&
to.user_push_notification.send(name)
PushNotificationJob.perform_later(
from: from,
to: to,
message: message(:push),
name: name,
created_at: created_at.iso8601
)
end
end
def message(gate_scope)
# gate_scope can be 'sms' or 'push' or 'email.body' if we have nested yml in translations
I18n.t(
"notification.#{model}.#{name}.#{gate_scope}",
from: from,
to: to,
created_at: created_at
)
end
end
我创建了一个NotificationsChannel
,看起来像这样:
class NotificationsChannel < ApplicationCable::Channel
def subscribed
stream_from "notification_channel:#{current_user.id}"
end
def unsubscribed
stop_all_streams
end
end
还有一个PushNotificationJob
看起来像这样:
class PushNotificationJob < ApplicationJob
queue_as :default
def perform(from:, to:, message:, name:, created_at:)
NotificationsChannel.broadcast_to(
to,
type: name,
caller: from,
message: message,
created_at: created_at
)
end
end
一切正常,唯一缺少的链接是我可以在前端将其广播给用户的部分: 到目前为止,这是我在JavaScript方面所拥有的。
App.notificationsChannel = App.cable.subscriptions.create(
'NotificationsChannel',
{
connected: function() {
// Called when the subscription is ready for use on the server
console.log('Notification Channel connected.');
},
disconnected: function() {
// Called when the subscription has been terminated by the server
console.log('Notification Channel disconnected.');
},
received: function(data) {
// Called when there's incoming data on the websocket for this channel
console.log(data);
}
}
);
// App.notificationsChannel.send({ test: 'data' });
除了连接和断开连接中的内容外,我无法在浏览器控制台中打印任何内容。
创建约会后,这就是我的终端日志。
知道我还缺少什么以及需要做什么吗?
顺便说一句,我也在路由文件中创建了这些路由URL
resources :notifications, only: :index do
collection do
post 'seen_all', to: "notifications#seen_all"
end
member do
post :seen
end
end
最后是我的NotificationsController
。
module API
module V1
class NotificationsController < ApiController
before_action :set_user
def index
@user.incoming_notifications.page(params[:page]).per(params[:per_page])
end
def seen_all
Notification.where(seen: false, to_id: @user.id).update(seen: true)
end
def seen
@user.incoming_notifications.find_by(id: params[:id]).seen!
end
private
def set_user
@user = current_user
end
end
end
end
请指导我如何在浏览器控制台中打印通知,然后再通过API在React中使用它。谢谢。
答案 0 :(得分:2)
请检查延迟的作业日志以获取更多信息。 尝试以下操作:
def perform(from:, to:, message:, name:, created_at:)
ActionCable.server.broadcast "notification_channel:#{to.id}", { type: type, caller: caller.name, message: message, created_at: created_at }
end
此处的提示:使用after_commit: :do_something, on: [:create, :update]
而不是after_create
。这样可以确保仅在成功创建约会后才触发通知。
答案 1 :(得分:0)
您可以使用以下教程来完成此工作。 这很容易实现 Using Action Cable With React我已经遵循了一些项目的指导原则。