This article is the first step for a fledgling engineer! This is an article of AdventCalendar2020 Day 19.
This is a general application that allows you to comment on user posts. (Use devise for user registration) Currently, we have not set validation for comment, so it is possible to post blank.
The view and controller of the comment function before implementation are as follows.
ruby:post_images/show.html.erb * Excerpt from the comment posting part only
<%= form_with model:[@post_image, @comment], local:true do |f| %>
<div class="row">
<div class="col-sm-12">
<%= f.text_area :comment, rows:'5', class: "form-control",placeholder: "Comment here" %>
</div>
</div>
<%= f.submit "Send", class: "btn btn-lg btn-base-1 mt-20 pull-right" %>
<% end %>
post_images/controller.rb
def show
@post_image = PostImage.find(params[:id])
@comment = Comment.new
end
comments/controller.rb
def create
post_image = PostImage.find(params[:post_image_id])
comment = current_user.comments.new(comment_params)
comment.post_image_id = post_image.id
comment.save
redirect_to post_image_path(post_image)
end
private
def comment_params
params.require(:comment).permit(:comment)
end
models/comments.rb
validates :comment, presence: true
If the save of the local variable comment fails, the comment is known to contain the error content. In order to reflect the status in view (display an error message), it is necessary to redefine the comment containing the error content in the instance variable @error_comment.
comments/controller.rb
def create
post_image = PostImage.find(params[:post_image_id])
comment = current_user.post_comments.new(comment_params)
comment.post_image_id = post_image.id
#6 lines added (if ~ end)--------------------------------
if comment.save
redirect_to post_image_path(post_image)
else
@error_comment = comment
render 'post_image/show'
end
#-----------------------------------------------
end
private
def comment_params
params.require(:comment).permit(:comment)
end
Pass the @error_comment you just redefined to view.
html:post_images/show.html.erb * Excerpt from the comment posting part only
<%= form_with model:[@post_image, @post_comment], local:true do |f| %>
----Added display of error messages------------------------------------------------
<% if @error_comment.present? %>
<div id="error_explanation">
<h2><%= @error_comment.errors.count %>An error has occurred.</h2>
<ul>
<% @error_comment.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
--------------------------------------------------------------------------
<div class="row">
<div class="col-sm-12">
<%= f.text_area :comment, rows:'5', class: "form-control",placeholder: "Comment here" %>
</div>
</div>
<%= f.submit "Send", class: "btn btn-lg btn-base-1 mt-20 pull-right" %>
<% end %>
Display only when there is an error in <% if @ error_comment.present?%> On the second line. @Error_comment is not defined when displaying the show page because it is a variable that is redefined only when comment is an empty post. Without <% if @ error_comment.present?%>, The following error will occur.
If the comment posting fails, it is rendered to the show page of post_image, but the instance variable required to display the view of the show is not in the create action of the comment controller, so it is necessary to add it.
post_images/controller.rb
def show
@post_image = PostImage.find(params[:id])
@post_comment = PostComment.new
end
Append.
comments/controller.rb
def create
post_image = PostImage.find(params[:post_image_id])
comment = current_user.post_comments.new(post_comment_params)
comment.post_image_id = post_image.id
if comment.save
redirect_to post_image_path(post_image)
else
@error_comment = comment
#------post_Added show action for image---------------
@post_image = PostImage.find(params[:id])
@post_comment = PostComment.new
#-------------------------------------------------
render 'post_image/show'
end
end
private
def comment_params
params.require(:comment).permit(:comment)
end
Now when I post a comment, I get the following message saying that I can't find it because I don't have an id. To be exact, there is an id, but the name has changed and it is different, so it feels like I can not find the id. If you check with rails routes,
Prefix | Verb | URI Pattern | Controller#Action |
---|---|---|---|
post_image | GET | /post_images/:id(.:format) | post_image#show |
post_image_comments | POST | /post_images/:post_image_id/comments(.:format) | comment#create |
In the show action, the parameter id of post_images was: id, but in the case of create action, the parameter id is post_image_id. Therefore, change the parameter id to post_image_id.
comments/controller.rb
def create
post_image = PostImage.find(params[:post_image_id])
comment = current_user.post_comments.new(post_comment_params)
comment.post_image_id = post_image.id
if comment.save
redirect_to post_image_path(post_image)
else
@error_comment = comment
#----------Change(:id → :post_image_id)------------------------
@post_image = PostImage.find(params[:post_image_id])
#------------------------------------------------------------
@post_comment = PostComment.new
render 'post_image/show'
end
end
private
def comment_params
params.require(:comment).permit(:comment)
end
It was a very roundabout explanation, but I hope it will be helpful for beginners who are having trouble solving errors.
Recommended Posts