I implemented the comment function (comment) by using ajax to partially transition. I will leave the stumbling block when implementing the update function.
Ruby 2.7.2 Rails 6.0.3.4
Update the content (body) of the comment (comment) associated with the post. The controller looks like this.
comment_controller.rb
class CommentsController < ApplicationController
def update
@comment = current_user.comments.find(params[:id])
if @comment.update(comment_update_params)
render json: @comment , status: :ok
else
render json: { comment: @comment, errors: { messages: @comment.errors.full_messages } }, status: :bad_request
end
end
private
def comment_update_params
params.require(:comment).permit(:body)
end
end
The js code looks like this.
comment_edit.js
$(function() {
//Excerpt
$.ajax({
type: 'PATCH',
url: '/comments/' + commentId,
data: {
comment: {
body: body
},
},
dataType: 'json',
}).done(function (data) {
//Success processing
}).fail(function () {
//Failure handling
});
})
});
If the comment update is successful, the success process will be performed. However, I got a 422 error. When I checked the Rails log, it was as follows.
Processing by CommentsController#update as JSON
Parameters: {"comment"=>{"body"=>"Ah ah"}, "id"=>"36"}
Can't verify CSRF token authenticity.
Completed 422 Unprocessable Entity in 2ms (ActiveRecord: 0.0ms | Allocations: 834)
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
It says Can't verify CSRF token authenticity.
.
Apparently, the cause was that the CSRF token was not granted.
I mentioned csrf_meta_tags
in application.html.erb
.
ruby:application.html.erb
<!DOCTYPE html>
<html>
<head>
<title>title</title>
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
</head>
It seems to be described as a countermeasure for CSRF. For details, please check the Rails guide. Rails Security Guide
Based on this, we added the following code in the form of granting a CSRF token.
comment_edit.js
$(function() {
//Excerpt
$.ajax({
type: 'PATCH',
url: '/comments/' + commentId,
data: {
comment: {
body: body
},
},
//Postscript from here
headers: {
'X-CSRF-Token' : $('meta[name="csrf-token"]').attr('content')
},
//Postscript up to here
dataType: 'json',
}).done(function (data) {
//Success processing
}).fail(function () {
//Failure handling
});
})
});
Then it worked fine.
The PC is honest. I only receive what I was instructed to do (laughs)
I think there are other ways to write it. You may want to refer to the Rails guide below. [Rails Guide Ajax CSRF Token](https://railsguides.jp/working_with_javascript_in_rails.html#ajax%E3%81%AEcsrf%EF%BC%88cross-site-request-forgery%EF%BC%89%E3%83% 88% E3% 83% BC% E3% 82% AF% E3% 83% B3)
Recommended Posts