Использование объекта Rails ActionCable в интерфейсе React. - PullRequest
0 голосов
/ 27 ноября 2018

У меня есть модель 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' });

Я не могу получить что-либо для печати в консоли браузера, кроме того, что есть при подключении и отключении.

После создания Встречи вот так выглядит мой журнал терминала.

enter image description here

Есть идеи, что еще мне не хватает и что мне нужно делать?

Кстати, я также создал 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

Пожалуйста, расскажите мне, как распечатать уведомления в консоли браузера, а затем использовать их в React через API.Благодарю.

Ответы [ 2 ]

0 голосов
/ 27 ноября 2018

Пожалуйста, проверьте журналы отложенных заданий для получения дополнительной информации.Попробуйте следующее:

 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.Это обеспечит запуск уведомления только после успешного создания встречи.

0 голосов
/ 27 ноября 2018

вы можете использовать следующий учебник, чтобы получить эту работу.Этого довольно просто достичь Использование Action Cable с React Я уже следовал рекомендациям для нескольких проектов.

...