You can easily setup comments for post like the same way as post.
The basic steps include
1. Generate the comment model and controller
2. add fields to comment table and run the migration
3. set up the database relations between the Comment model, the User model, and the Post model.
# in user.rb
has_many :comments
# in post.rb
has_many :comments
# in comment.rb
belongs_to :user
belongs_to :post
4. add routes for comments
resources :posts do
resources :comments
end
5. set up the backend logic so that users can post comments to photos.
The comments controller should look like this
class CommentsController < ApplicationController
def create
@post = Post.find(params[:post_id])
@comment = @post.comments.create(comment_params.merge(user_id: current_user.id))
if @comment.valid?
redirect_to root_path
else
flash[:alert] = "Invalid params"
redirect_to root_path
end
end
private
def comment_params
params.require(:comment).permit(:text, :post_id)
end
end
The thing that is new is .merge(user_id: current_user.id)
. Before, we did things like current_user.posts.create(post_params) which hooked up the post and the current_user. Here, since the comment belongs to a Post and a User as well, we can't chain the method like this: current_user.@post.comments.create
.
However, we can use this merge method to merge in the user_id and set it to current_user.id. That's what .merge(user_id: current_user.id) is doing right here.
6. Don't forget to add validations as well.
Make sure that we get valid data to be saved into our database. Specifically, we need to make sure that the text, post_id, and user_id is present.
7. Create the comments form so that users can post comments to photos.
In index.html.erb
file of posts. Inside our loop, let's create a form for each instance of a post. The form will look like this:
<%= simple_form_for Comment.new, url: post_comments_path(post), method: :post do |f| %>
<%= f.input :text, label: 'Comment', placeholder: 'Add a comment...', label_html: {class: 'mt-4'}, input_html: {class: 'mt-2 md:max-w-[50%]'} %>
<%= f.submit 'Post', class: 'text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-blue-600 dark:hover:bg-blue-700 focus:outline-none dark:focus:ring-blue-800' %>
<% end %>
8. Display all of the comments for each post above the form. You can do this with a simple loop. Try to do this yourself and see how far you get!
What you need to do:
- Display the name of the user that posted the comment
- Display the comment text
9 Set up the backend logic for deleting comments. It's very similar to what we did for posts.
In our comments_controller.rb, let's add a destroy method that will delete a comment and then redirect the user to the root_path.
The code now should look like this
<% post.comments.each do |comment| %>
<div class="px-2">
<p class="mb-3"><%= comment.user.email.split('@').first %> <%= comment.text %></p>
<%= link_to 'Delete', post_comment_path(post_id: post.id, id: comment.id), method: :delete, class: 'text-white bg-red-700 hover:bg-red-800 focus:ring-4 focus:ring-red-300 font-medium rounded-lg text-sm px-5 py-2.5 me-2 mb-2 dark:bg-red-600 dark:hover:bg-red-700 focus:outline-none dark:focus:ring-red-800' %>
</div>
<% end %>