Application monitoring that helps developers get it done.
Deploy apps to servers that you own and control.
Now that we have posts fully set up, it's time to customize the comments feature to fit the needs of Lorem News. Just like with posts, I wrote down a basic set of rules for how comments should behave within our application:
There are several changes we need to make to the Rails-generated scaffold to enforce these rules properly.
Currently, the comments resource is a top-level resource, meaning it exists independently, just like posts. However, comments should always be associated with a post, so we need to nest the comments resource inside posts.
Let’s update our routes file to reflect this:
resources :posts do
resources :comments, only: [:create, :edit, :update, :destroy], shallow: true
end
This setup ensures:
Since comments depend on posts, we need to update the CommentsController accordingly.
Remove Unnecessary Actions Since comments are not standalone resources, we can delete the following actions: index, show, and new.
class CommentsController < ApplicationController
before_action :set_post, only: %i[:create]
before_action :set_comment, only: %i[:edit, :update, :destroy]
# No need for index, show, or new
def create
@comment = @post.comments.new(comment_params.merge(user: Current.user))
if @comment.save
redirect_to @post, notice: "Comment was successfully created."
else
render "posts/show"
end
end
private
def set_post
@post = Post.find(params.expect(:post_id))
end
def set_comment
@comment = Comment.find(params[:id])
end
def comment_params
params.expect(comment: [ :body ])
end
end
Since comments are now nested under posts, we need to update the form to reflect that.
<%= form_with(model: [@post, comment]) do |f| %>
<div>
<%= f.label :body, "Add a comment:" %>
<%= f.text_area :body, rows: 3 %>
</div>
<div>
<%= f.submit "Post Comment" %>
</div>
<% end %>
Since comments belong to posts, we should render them directly on the post’s show page (posts/show.html.erb):
<%= render "comments/form", comment: @post.comments.new %>
This ensures comments are only visible under their respective posts. We need to ensure that we can see the collection of comments on the Post show page too.
<%= render @post.comments %>
Currently, any user can see the comment form, even if they’re not logged in. Let’s fix that.
<% if Current.user.present? %>
<%= render "comments/form", post: @post, comment: @post.comments.new %>
<% end %>
We need to make a tweak to our authentication controller to ensure that a logged in user can see the form, by adding a :resume_session before action. Now only authenticated users can see the comment form.
Next, we need to ensure only the comment’s creator can edit or delete it by modifying CommentsController:
before_action :set_comment, only: [:edit, :update, :destroy]
def set_comment
@comment = Comment.find(params.expect(:id))
raise NotAuthorized unless @comment.user == Current.user
end
At this point, we have:
Next, we’ll polish the UI further and refine the styling and user experience to make interactions smoother.