As a comment function linked to posts without creating a new chat room We have implemented an implementation that allows you to post and delete comments in real time.
This time we will implement the basics of the comment function that is the basis of this implementation! To real-time comment function (2/2) with Action Cable
What is Action Cable? It is a framework that can implement the immediate update function with the same description as a normal Rails application. The implementation contents are Ruby coding required for saving and sending messages, and JavaScript coding to display the saved messages immediately.
What is Channel A channel is a server-side mechanism that realizes an immediate update function. As shown above, you can set the data route and display the sent data on the client screen.
Stream_from is a method that associates a server with a client. It is prepared in advance in Action Cable.
Broadcast refers to the path of data sent from the server. Sends data to the client via broadcast.
Action uses create and destroy I want to link it to posts, so I'll nest it with posts
#routes.rb
Rails.application.routes.draw do
devise_for :users, controllers: { registrations: 'users/registrations' }
root to: "posts#index"
resources :users
resources :posts do
resources :comments, only: [:create, :destroy]
end
end
In comments_controller to display comments on the post page Only describe the creation and destory of comments
#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
Write a description to display comments in posts_controller This time we have implemented a detail page in the post so the action is show
#posts_controller
def show
@post = Post.find(params[:id])
@comment = Comment.new
@comments = @post.comments
end
Call the comment display part and the comment posting part using render
#show.html.erb
<div class="row">
<ul>
<li class="comment-create">
<h3 class="text-left title">Talk room</h3>
</li>
<li class="comments_area">
<%= render partial: 'comments/index', locals: { comments: @comments } %>
</li>
</ul>
<% if user_signed_in? %>
<div id="comment-create">
<h3 class="text-left">Post a comment</h3>
<%= render partial: 'comments/form', locals: { comment: @comment, post: @post } %>
</div>
<% end %>
</div>
Comment display part
#_index.html.erb
<% @comments.each do |comment| %>
<% unless comment.id.nil? %>
<li class="comment-container" id="test-<%=comment.id%>">
<div class="comment-box">
<div class="comment">
<div class="comment-nickname">
<p><%= link_to "@#{comment.user.nickname}", user_path(comment.user.id) %></p>
</div>
<div id="comment-entry">
<span style="font-weight:bold;"><%= comment.content %></span>
<%= comment.created_at.to_s(:datetime_jp) %>
<% if comment.user == current_user %>
<%= link_to post_comment_path(comment.post_id, comment.id), method: :delete, remote: true do %>
<button id="<%=comment.id%>" id="delete-btn">Delete</button>
<% end %>
<% end %>
</div>
</div>
</div>
</li>
<% end %>
<% end %>
<!--Comment content(3rd and subsequent cases) ------------------------------------------------------------------>
<div class="collapse" id="collapseExample">
<% @comments.offset(2).each do |comment| %>
<% unless comment.id.nil? %>
<li class="comment-container" id="test-<%=comment.id%>">
<div class="comment-box">
<div class="comment">
<div class="comment-nickname">
<p><%= link_to "@#{comment.user.nickname}", user_path(comment.user.id) %></p>
</div>
<div id="comment-entry">
<span style="font-weight:bold;"><%= comment.content %></span>
<%= comment.created_at.to_s(:datetime_jp) %>
<% if comment.user == current_user %>
<%= link_to post_comment_path(comment.post_id, comment.id), method: :delete, remote: true do %>
<button id="<%=comment.id%>" id="delete-btn">Delete</button>
<% end %>
<% end %>
</div>
</div>
</div>
</li>
<% end %>
<% end %>
</div>
Posting part of comment
#_form.html.erb
<%= form_with(model: [@post, @comment], url: post_comments_path(@post.id) ) do |f| %>
<%= f.text_area :content, class: "input-mysize" %>
<%= f.submit "Send", class: "btn btn-outline-dark comment-submit float-right", id:"submit_btn" %>
<% end %>
Omit the model and migration files!
Recommended Posts