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.
Rails 5.2.3
Ruby 2.6.0
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 ...)
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.)
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.
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.)
- Execute the JavaScript code written in the file
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.
It's not in shape yet, but when it's slimy, the posts will be displayed: relaxed:
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
.
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).
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
With the implementation so far, the implementation of the image mentioned above has been realized.
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.