[RAILS] remote: true to POST ajax posts.

What did you do

I'm making an app with Rails. As the title says, I made a form that allows you to post ajax with remote: true. It wasn't the first time, so I made it, but I'm not familiar with the procedure and way of thinking, so I'll write it down as a notebook for myself.

The execution environment is as follows.

Reference article

For implementation, I referred to the following articles very much.

[Rails] remote: How to implement Ajax form submission with true?

This procedure is also similar to this one, so if you want a detailed explanation, I think you should read the above article. (This is just a memo for myself ...)

Implementation method

What I made

Image from Gyazo What I tried to make this time is a mechanism like this that allows you to post comments when you are slimy on the post. In terms of DB structure, there are comments associated with the posts table. (The image is under construction, so it may be replaced soon.)

remote: Try to make a true form

First of all, I made a form to post comments as usual. In addition, the class for decoration and the elements not related to this implementation are omitted. (Hereafter, the same for all codes)

= form_with model: [@post, @comment] do |f|
  = f.text_field :text
  = f.submit 'Post'

form_with defaults to remote: true, so it's a very simple form without local: true.

controller

comments_controller.rb


def create
  @comment = @post.comments.build(comment_params)
  @comment.save!
end

I also made the controller very simple. This time, the main purpose is to check the behavior of remote: true, so

** 1) Separate html and js processing with redpond_to, format ** ** 2) Error handling when @comment could not be saved **

Is not implemented.

  1. I would like to write a separate article about it, but I would like to add that the above two points are also taken into consideration when actually implementing it.

Anyway, the controller above will cause ** js format create.js.erb to be called **. create.js.erb

By the way, **. Js.erb is an unfamiliar file name, isn't it? What this file can do is (the following is a quote from the this article introduced earlier.)

  1. Execute the JavaScript code written in the file
  1. You can use ERB tags
  2. Instance variables can be used

You can do the above. It's convenient: relaxed: So, for example, if you write the following in create.js.erb mentioned above ...

erb:comments/create.js.erb


$('.comments').append("<%= @comment.text %>");

That alone can create a view like this.

Image from Gyazo

It's not in shape yet, but when it's slimy, the posts will be displayed: relaxed:

Supplement 1: About the view to which you post

In addition, the order has changed ... The view of ** destination ** to be posted this time has such a structure.

.comments
  = render @comments

Under the .comments class, the contents of @ comments are expanded and called out (← here, it is a very broken writing style, so if you say "???" [this article ](See https://qiita.com/tanutanu/items/26da2e6bf89c2464657f))

With this code I wrote earlier

erb:comments/create.js.erb


$('.comments').append("<%= @comment.text %>");

The new @ comment you posted will be added to the end of the @ comment group in .comments.

Supplement 2: About the code actually written

Actually, with the above code alone, ** after posting, the posted comments will continue to remain in the form **. Therefore, I actually write the following code.

= form_with model: [@post, @comment], class: 'js-comment-form' do |f| #Postscript
  = f.text_field :text
  = f.submit 'Post'

Add a class called js-comment-form to the form and

erb:comments/create.js.erb


$('.comments').append("<%= @comment.text %>");
$('.js-comment-form')[0].reset();

After adding the text, the contents of .js-comment-form are reset (empty).

Partial call in create.js.erb

Anyway, now that I can post asynchronously, I'd like to make it look a little richer.

In conclusion, the code I wrote is below.

erb:comments/create.js.erb


$('.comments').append("<%= j(render 'comment', comment: @comment) %>");

First, in the render'comment' part, we call the partial of comment/_comment.

(Returning to the ** Supplement 1 ** section above, this time, the view of the ** destination ** where you post a comment is as follows. Therefore, there is a partial called _comment.)

.comments
  = render @comments

Next, the j method escapes the JavaScript code. I read these two articles to deepen my understanding of this area.

-[Rails] remote: How to implement Ajax form submission with true? --Call and update partial template

I will omit the details of the partial contents, but it looks like this. There is no problem writing this using haml or slim.

comments/_comment.html.slim


div
 =Icon image
 = comment.user
 div
   = comment.text
    div
      =Delete icon
      =Edit icon

Complete!

With the implementation so far, the implementation of the image mentioned above has been realized. Image from Gyazo

I was a little weak, but by writing an article at the end of the paragraph, I was able to deepen my understanding of the implementation and also refactor it: relaxed:

From now on, I would like to do my best to implement error handling and edit / delete asynchronously.

Recommended Posts

remote: true to POST ajax posts.
[rails] How to post images
post to Qiita patching version
post to Qiita patching version