[RUBY] Erstellen Sie einen Team-Chat mit Rails Action Cable

Einführung

Ich habe eine Team-Chat-Funktion mit Action Cable im Portfolio erstellt, damit ich sie ausgeben kann.

Referenzartikel

Ich habe auf den folgenden Artikel verwiesen. Vielen Dank. ・ Mit Schienen 5 + Aktionskabel herstellen! Einfache Chat-App (aus dem Demo-Video von DHH)[Rails 6.0] Erstellen Sie einen Echtzeit-Chat mit Action Cable und Devises gierigem Set (überarbeitete Version)

Code

Passen Sie den Code im Referenzartikel an, um einen Chat für jedes Team zu senden. Dieses Mal erstellen wir eine Chat-Aktion auf dem Team-Controller, damit wir Chats senden können. Erstellen Sie andere Teile als das Aktionskabel gemäß der MVC-Struktur.

model Das Modell beschreibt die Viele-zu-Viele-Beziehung zwischen dem Teammodell und dem Benutzermodell. Darüber hinaus wird das Nachrichtenmodell, das den Inhalt des Chats darstellt, als Modell der Zwischentabelle zwischen dem Benutzer und dem Team erstellt.

app/models/team.rb


class Team < ApplicationRecord #Teammodell
  belongs_to :owner, class_name: 'User', foreign_key: :owner_id
  has_many :team_assigns, dependent: :destroy 
  has_many :members, through: :team_assigns, source: :user
  has_many :messages, dependent: :destroy
end

app/models/user.rb


class User < ApplicationRecord
  # Include default devise modules. Others available are:
  # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable
  has_one_attached :icon #Fügen Sie ein Benutzersymbol in Active Storage hinzu
  has_many :team_assigns, dependent: :destroy
  has_many :teams, through: :team_assigns, source: :team
  has_one :owner_team, class_name: 'Team', foreign_key: :owner_id, dependent: :destroy
  has_many :messages, dependent: :destroy
end

app/models/team_assign.rb


class TeamAssign < ApplicationRecord
  belongs_to :team
  belongs_to :user
end

app/models/message.rb


class Message < ApplicationRecord
  belongs_to :user
  belongs_to :team
end

controller Der Controller hat eine Chat-Aktion innerhalb des Teams erstellt. Erhalten Sie die Team-ID über den Link, suchen Sie in der Team-Klasse, rufen Sie den Chat des Teams ab und übergeben Sie ihn zur Anzeige.

app/controllers/teams_controller.rb


  def chat
    @team = Team.find(params[:id])
    messages = @team.messages
  end

view Seit ich Bootstrap angewendet habe, verwende ich Container, Alert usw. Grundsätzlich wird der empfangene Chat auf dem Bildschirm angezeigt, indem eine Nachricht teilweise gerendert wird. Wir haben auch ein Formular zum Senden von Chats.

html:app/views/teams/chat.html.erb


<h1 id="chat" data-team_id="<%= @team.id %>">
  <%= @team.name %>Chatraum
</h1>

<div class="container">
  <% if @team.members.count == 1 %>
    <div class="alert alert-danger" role="alert">
Es gibt keine Teammitglieder, mit denen Sie chatten können. Fügen Sie Mitglieder aus dem Teambildschirm hinzu
    </div>
  <% end %>
  <form class="form-group">
    <label>Plaudern:</label>
    <input type="text" data-behavior="team_speaker", placeholder="Inhalt", class="form-control">
  </form>
  <div id="messages_<%= @team.id %>">
    <ul class="list-group">
      <%= render @messages %>
    </ul>
  </div>
</div>

html:app/views/messages/_message.html.erb


<div class="message">
  <li class="list-group-item">
    <div class="row">
      <div class="col-md-2">
        <% if message.user.icon.attached? %>
          <%= image_tag message.user.icon.variant(resize:'50x50').processed %>
        <% end %>
        <p><%= message.user.name %></p>
      </div>
      <div class="col-md-10">
        <small class="text-muted"><%= l message.created_at, format: :short %></small><br>
        <%= message.content %>
      </div>
    </div>
  </li>
</div>

Implementieren Sie von hier aus das Aktionskabel. Erstellen Sie zunächst einen Teamkanal. Verzeichnisse und Dateien werden für den Kanal erstellt.

$ rails g channel team

coffeescript Beschreiben Sie zunächst die Einstellungen für die Überwachung des Servers über den Browser. Verwenden Sie jQuery, um die Team-ID anzuzeigen und einen Kanal zum Abonnieren zu erstellen.

app/assets/javascripts/channels/team.coffee


App.team = App.cable.subscriptions.create {
  channel: "TeamChannel",
  team_id: $("#chat").data("team_id")}, 

  connected: ->
    # Called when the subscription is ready for use on the server

  disconnected: ->
    # Called when the subscription has been terminated by the server

  received: (data) ->
    #Empfangen Sie den Chat, der von der Sprechmethode auf der Kanalseite empfangen wurde
    $('#messages_'+data['team_id']).prepend data['message']

  speak: (message) ->
    team_id = $('#chat').data('team_id')
    @perform 'speak', message: message, team_id: team_id

$(document).on 'keypress', '[data-behavior~=team_speaker]', (event) ->
  if event.keyCode is 13 # return = send
    App.team.speak event.target.value
    event.target.value = ''
    event.preventDefault()

channel.rb Beschreiben Sie als Nächstes die Einstellungen für die Überwachung des Browsers vom Server aus. Die @perform speak des Browsers ruft die serverseitige Sprechaktion auf. Die Sprechaktion erstellt eine Instanz der Nachrichtenklasse basierend auf den vom Browser empfangenen Informationen.

app/channels/team_channel.rb


class TeamChannel < ApplicationCable::Channel
  def subscribed
    stream_from "team_channel_#{params['team_id']}" #Zeigen Sie, welches Team Sie überwachen
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end

  def speak(data)
    message = Message.create!(
      content: data['message'],
      team_id: data['team_id'],
      user_id: current_user.id
    )
  end
end

Ich verwende current_user im Kanal, aber dafür muss ich den folgenden Code hinzufügen.

app/channels/application_cable/connection.rb


module ApplicationCable
  class Connection < ActionCable::Connection::Base
    identified_by :current_user

    def connect
      self.current_user = find_verified_user
    end

    private

      def find_verified_user
        verified_user = User.find_by(id: env['warden'].user.id)
        return reject_unauthorized_connection unless verified_user
        verified_user
      end
  end
end

Nachrichtenmodell

Lässt den Job ausführen, wenn eine Instanz im Nachrichtenmodell erstellt wird (nach dem Festschreiben).

app/models/message.rb


class Message < ApplicationRecord
  belongs_to :user
  belongs_to :team
  after_create_commit { MessageBroadcastJob.perform_later self } #Nachtrag
end

job Beschreiben der Einstellungen zum Senden der erstellten Nachricht vom Job an den Browser. Erstellen Sie zunächst einen Nachrichtenübertragungsjob mit dem Befehl Rails.

$ rails g job MessageBroadcast

Wenn Sie ActiveStorage verwenden und in ApplicationController.renderer nicht http_host angeben, führt das Bildreferenzziel zu einem Fehler. Wenn Sie in der Produktion eine URL verwenden möchten, die mit https: // anstelle von http: // beginnt, müssen Sie https: true angeben.

app/jobs/message_broadcast_job.rb


class MessageBroadcastJob < ApplicationJob
  queue_as :default

  def perform(message)
    ActionCable.server.broadcast(
      "team_channel_#{message.team_id}",
      message: render_message(message),
      team_id: message.team_id
    )
  end

  private
    def render_message(message)
      renderer = ApplicationController.renderer.new(
        http_host: 'http_Hostnummer', #Local, localhost:3000. Je nach Produktionsumgebung geändert
    #https: true          https://Für URLs, die mit beginnen, müssen Sie diesen Code hinzufügen
      )
      renderer.render(partial: 'messages/message', locals: { message: message })
    end
end

Durch diesen Job wird der Teil der Nachricht an den Empfang von Kaffeeskript übergeben und in Echtzeit wiedergegeben.

Zusammenfassung

Ich fand ActionCable kompliziert, konnte aber die Weitergabe von Daten anhand von Referenzen verfolgen und verstehen. Aufgrund dieser Erfahrung wurde mir erneut klar, dass es wichtig ist, den Datenfluss einzeln zu verfolgen, auch wenn er kompliziert aussieht, und es ist die beste Verknüpfung, um binding.pry auf der Serverseite und Debugger auf der Browserseite zu verwenden. ..

Recommended Posts

Erstellen Sie einen Team-Chat mit Rails Action Cable
[Rails6] Erstelle eine neue App mit Rails [Anfänger]
[Schienenentnahme] Erstellen Sie eine einfache Entnahmefunktion mit Schienen
[Rails 5] Erstelle eine neue App mit Rails [Anfänger]
[Rails] Rails neu, um eine Datenbank mit PostgreSQL zu erstellen
Erstellen einer EC-Site mit Rails 5 ⑨ ~ Erstellen einer Warenkorbfunktion ~
Erstellen Sie eine Chat-App mit WebSocket (Tyrus) + libGDX + Kotlin
Erstellen Sie einen Spielplatz mit Xcode 12
Tutorial zum Erstellen eines Blogs mit Rails für Anfänger Teil 1
[Rails] Ich habe versucht, eine Mini-App mit FullCalendar zu erstellen
Eine Reihe von Schritten zum Erstellen von Ergebnissen für Portfolios mit Rails
Tutorial zum Erstellen eines Blogs mit Rails für Anfänger Teil 2
Tutorial zum Erstellen eines Blogs mit Rails für Anfänger Teil 0
Erstellen Sie mit Docker eine Vue3-Umgebung!
Erstellen Sie ein Portfolio mit Rails + Postgres SQL
[Rails Tutorial Kapitel 5] Erstellen Sie ein Layout
Erstellen Sie eine neue App mit Rails
Erstellen Sie meine Seite mit Rails
Erstellen Sie Ausnahmen mit einer Fluid-Schnittstelle
Erstellen Sie ein Maven-Projekt mit Befehlen
Erstellen Sie eine EC-Site mit Rails5 Boot ~ Bootstrap4-Einstellungen, Controller- / Aktionsdefinition ~
Erstellen Sie mit dem Befehl eine JAR-Datei
Erstellen Sie mit Dropwizard eine einfache Webanwendung
Erstellen Sie mit Spring Batch eine einfache On-Demand-Charge
[Ruby on Rails] Erstellen Sie mit Chartick ein kreisförmiges Diagramm der Summen nach Spalten
Erstellen eines einfachen Balkendiagramms mit MPAndroidChart
Erstellen Sie eine temporäre Klasse mit new Object () {}
Erstellen Sie trotzdem eine Anmeldefunktion mit Rails
Erstellen Sie mit Rails x LineBot eine App für die Zusammenfassung von technischen Nachrichten im LINEnews-Stil! [Teil 1]
[Rails] So erstellen Sie eine Teilvorlage
Erstellen Sie eine Website mit Spring Boot + Gradle (jdk1.8.x)
[Memo] Erstellen Sie mit Docker ganz einfach eine CentOS 8-Umgebung
Erstellen Sie eine CSR mit erweiterten Informationen in Java
Erstellen Sie mit Java + MySQL ein einfaches Bulletin Board
[Windows] [IntelliJ] [Java] [Tomcat] Erstellen Sie mit IntelliJ eine Umgebung für Tomcat 9
[Rails] So erstellen Sie ein Diagramm mit lazy_high_charts
[Java] Erstellen Sie eine Sammlung mit nur einem Element
Erstellen Sie ein SandBox-Konto mit Fastlane Spaces IP
Lassen Sie uns eine Suchfunktion mit Rails (Ransack) machen
Erstellen Sie eine Mehrschlüsselkarte mit einer Standardbibliothek
So erstellen Sie einfach ein Pulldown mit Rails
[Rails] So erstellen Sie eine Twitter-Freigabeschaltfläche
Erstellen Sie eine EC-Site mit Rails5 ⑤ ~ Kundenmodell ~
Ich habe einen LINE Bot mit Rails + Heroku gemacht
Erstellen Sie einen Web-API-Server mit Spring Boot
Erstellen Sie eine EC-Site mit Rails 5 ⑩ ~ Erstellen Sie eine Bestellfunktion ~
Erstellen Sie mit Docker eine Spring Boot-Entwicklungsumgebung
Ich habe mit Ruby On Rails ein Portfolio erstellt
Docker-Befehl zum Erstellen eines Rails-Projekts in einem einzigen Schlag in einer Umgebung ohne Ruby
[Einführung] Erstellen Sie eine Ruby on Rails-Anwendung