[Ruby] Comment function (Ajax) implementation

1 minute read

Collect for yourself.

Implementation

Controller model created

routes.erb


  resources :posts do
    resources :comments, only: [:create, :destroy]
  end

Comments are posted on the posts show page, displayed as a list, deleted, etc., so only create and destroy are created.

comments_controller.rb


class CommentsController <ApplicationController

  def create
    @post = Post.find(params[:post_id])
    @comment = @post.comments.new(comment_params)
    @comment.user_id = current_user.id
    @comments = @post.comments.all
    @comment.save
    render :create
  end

  def destroy
    @comment = Comment.find_by(id: params[:id], post_id: params[:post_id]).destroy
    @comment.destroy
    render :destroy
  end

  private
    def comment_params
      params.require(:comment).permit(:comment, :post_id)
    end
end

Changed the description part of transition with redirect_to etc. In the above case, For create action, create.js.erb When destroy action, destroy.js.erb It is supposed to fly to.

js.erb is a file that will be created later.

posts_controller.rb


class PostsController <ApplicationController
  def show
    @post = Post.find(params[:id])
    @comment = Comment.new
    @comments = @post.comments.all
  end
end

This time I will be able to post comments with posts / show

ruby:posts/show.html.slim


# Display comment list
.row
  .col-lg-4
    .col-lg-4

  #Required to rewrite in create.js.erb
      div id="comment-text"

    # Skip the comment list partly
        = render'comments/comment', comments: @comments

    
# Comment form
  .row
    .col-lg-3
    .col-lg-6.text-center
      .frame-post-show

        Remove the description of local: true to call the #js file
        = form_with(model: [@post, @comment]) do |f|

          = f.label :comment, class: "font-weight-bold col-lg-3 text-center"
          <br>
          = f.text_area :comment, :size=>"57x5"
          <br>

          .text-center= f.submit "Comment", class: "btn btn-outline-secondary btn-sm"


Manually create the _comment.html.slim file under the comments directory Paste the comment list part skipped by the partial.

ruby:comments/_comment.html.slim


- @comments.each do |comment|

  #Required to rewrite in destroy.js.erb
  div id="comment-#{comment.id}"
    .frame-post-comment
      = attachment_image_tag comment.user, :image, fallback:'noimage.png', size: "50x40", class: "mb-3"
      = link_to comment.user.name, user_path(comment.user)
      -if comment.user == current_user
      
    # add remote: true to call the js file
        = link_to'Delete', post_comment_path(comment.post, comment), method: :delete, remote: true, data: {confirm: "Are you sure you want to delete?" }, class: "btn btn-outline-danger btn -sm m-0 ml-3"
      <br>
      small.m-0= comment.created_at.to_s(:datetime_jp)
      .mt-4.mb-2= comment.comment


Create create.js.erb file manually under comments directory

ruby:comments/create.js.erb



# Rewrite the id="comment-text" part to the contents of _comment.html.slim without page transition
$('#comment-text').html("<%= j(render'comments/comment',{ comments: @comments }) %>");

Empty #f.text_area (If you do not write it, the comment contents will remain in the form even after posting)
$('textarea').val('');


Manually create the destroy.js.erb file under the comments directory

ruby:comments/destroy.js.erb



Hide posts with # "comment-#{comment.id}"
$('#comment-<%= @comment.id %>').remove();

**Complete! **