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)
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
#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
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>
${data.date}
<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();
},
});
})
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