Reputation: 117
I'm attempting to add basic comment functionality to posts. I am able to display the form for comments, but once saved they do not appear under the post. What I have so far:
class CommentsController < ApplicationController
def create
@topic = Topic.find(params[:topic_id])
@post = Post.find(params[:post_id])
@comment = current_user.comments.build(comment_params)
redirect_to [@topic, @post]
end
private
def comment_params
params.require(:comment).permit(:body)
end
end
class PostsController < ApplicationController
def show
@topic = Topic.find(params[:topic_id])
@post = Post.find(params[:id])
@comments = @post.comments
end
<h1><%= markdown_to_html @post.title %></h1>
<div class="row">
<div class="col-md-8">
<small>
<%= image_tag(@post.user.avatar.tiny.url) if @post.user.avatar? %>
submitted <%= time_ago_in_words(@post.created_at) %> ago by
<%= @post.user.name %>
</small>
<p><%= markdown_to_html( @post.body) %></p>
<h2>Comments</h2>
<% @comments.each do |comment| %>
<%= render partial: 'comments/comment', locals: {comment: comment} %>
<% end %>
<%= render partial: 'comments/form', locals: {topic: @topic, post: @post} %>
</div>
<div class="col-md-4">
<% if policy(@post).edit? %>
<%= link_to "Edit", edit_topic_post_path(@topic, @post), class: 'btn btn-success' %>
<% end %>
</div>
</div>
<p><%= p comment.body %></p>
<%= form_for [topic, post, post.comments.new] do |f| %>
<% if post.comments.new.errors.any? %>
<div class="alert alert-danger">
<h4>There are <%= pluralize(post.errors.count, "error") %>.</h4>
<ul>
<%= post.comments.new.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
<%= form_group_tag(post.comments.new.errors[:body]) do %>
<%= f.label :body %>
<%= f.text_area :body, rows: 1, class: 'form-control', placeholder: "Enter comment body" %>
<% end %>
<div class="form-group">
<%= f.submit "Save", class: 'btn btn-success' %>
</div>
<% end %>
I believe that should be all of the relevant code. The functionality seems to be there, but I must be doing something wrong with the submission process. Can someone point me in the right direction?
Thank you,
Matt
I added validates :body, length: {minimum: 5}, presence: true
to the post model and @comment = current_user.comments.create!(comment_params)
to the comment controller.
If I submit a comment form with <5 characters I do get the 'Validation failed: Body is too short (minimum is 5 characters)' message, but if the message meets the requirements it will submit and nothing will happen.
Upvotes: 0
Views: 1307
Reputation: 7434
Notice that you have associated the comment to a User
with the following line
current_user.comments.create(...)
however nowhere do you associate the newly created comment to the Post
. When you subsequently call @post.comments
, you won't get the Comment
back because it was never attached to that Post
Since you have access to the @post
from within the CommentsController
, I recommend doing something like this in your create
action
def create
# ...
current_user.comments.create(comment_params_with_post)
# ...
end
def comment_params_with_post
comment_params.merge(post: @post)
end
Upvotes: 1
Reputation: 9961
You forget to save comment. Instead of:
@comment = current_user.comments.build(comment_params)
you should use
@comment = current_user.comments.create(comment_params)
collection.build(attributes = {}, …)
Returns one or more new objects of the collection type that have been instantiated with attributes and linked to this object through a foreign key, but have not yet been saved.
Here is more details.
Upvotes: 1