[RUBY] Real-time comment function with Action Cable (2/2)

★ Implement real-time comment function with Action Cable

As a comment function linked to posts without creating a new chat room Implement that allows you to post and delete comments in real time

This time we will implement the real-time comment function The link below summarizes a little about Action Cable. To the basics of the comment function (1/2)

❶ Check the controller

After creating and destroying comments Specify the information you want to send as data to javascript here

#comments_controller.rb
class CommentsController < ApplicationController
  def create
    @post = Post.find(params[:post_id])
    #Create a comment associated with a post
    @comment = @post.comments.build(comment_params)
    @comment.user_id = current_user.id
    if @comment.save
      ActionCable.server.broadcast 'message_channel', content: @comment, user: @comment.user, date: @comment.created_at.to_s(:datetime_jp), id: @comment.id,post: @comment.post
    end
  end

  def destroy
    @post = Post.find(params[:post_id])
    @comment = Comment.find(params[:id])
    if @comment.destroy
      ActionCable.server.broadcast 'delete_channel', id: @comment.id
    end
  end

  private
  def comment_params
    params.require(:comment).permit(:content, :post_id, :user_id).merge(user_id: current_user.id)
  end
end

❷ Connect controller and javascript file with channel

#message_channel.rb
class MessageChannel < ApplicationCable::Channel
  def subscribed
    stream_from "message_channel"
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end
end
#delete_channel.rb
class DeleteChannel < ApplicationCable::Channel
  def subscribed
    stream_from "delete_channel"
  end

  def unsubscribed
    # Any cleanup needed when channel is unsubscribed
  end

end

❸ Describe the process you want to implement in real time with javascript

Display date and time specified by format Organize notation for embedding code in character strings

#message_channel.js
import consumer from "./consumer"
window.addEventListener('load', function(){

consumer.subscriptions.create("MessageChannel", {
  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) {
    const html = `<div id="test-${data.id}">
    <p><a href="/users/${data.user.id}">@${data.user.nickname}</a></p>
                  <span style="font-weight:bold;">${data.content.content}</span>
                  &nbsp;${data.date}
                  &nbsp;<a id="delete-btn", data-method="delete" href="/posts/${data.post.id}/comments/${data.id}"><button id="${data.id}">Delete</button></a>
                  </div>`;

    const messages = document.getElementById('collapseExample');
    const newMessage = document.getElementById('comment_content');
    messages.insertAdjacentHTML('beforeend', html);
    newMessage.value='';

      var countComment = document.getElementsById('collapseExample').length;
      console.log(countComment)
  }
});
})

flow of delete_channel.js Put the comment ID in the comment container element in advance.

#_index.html.erb
<li class="comment-container" id="comment-#{comment.id}">

Find this and delete it

Also, by setting (comment-$ {data.id}) I only get the ID of the comment I'm sending with @ comment.id on the controller, so I don't think it's necessary Since not only 137 but also an extra part was sent like id: 137, the specification was made finer.

It is important to use the debugger diligently and implement it while checking.

#delete_channel.js
import consumer from "./consumer"
window.addEventListener('load', function(){
consumer.subscriptions.create("DeleteChannel", {
  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) {

    const test = document.getElementById(`${data.id}`)
    const container = document.getElementById(`test-${data.id}`);
    console.log(container)
    container.remove();
    
    },
    
});
})

★ The following are possible alternative plans for the deletion function implemented this time.

After inserting an element with insertAdjacentHTML, add an onclick event handler to that element and send a delete request within the handler

You can shorten the description by using JQuery, but this time I implemented it only with Javascript for studying

Recommended Posts

Real-time comment function with Action Cable (2/2)
Real-time comment function with Action Cable (1/2)
Implemented comment function
I want to test Action Cable with RSpec test
Create a team chat with Rails Action Cable
Comment function (Ajax) implementation
With Kotorin ―― 7. Scoping Function
Serverless Function with Micronaut
Chat function that is updated immediately (implementation of Action Cable)
Introduced graph function with rails
Java to play with Function
Login function with Spring Security
Login function implementation with rails
About immediate comment update function
Draw and understand Action Cable
App creation comment function asynchronous
Implement search function with form_with