I have a Post model, and a Comment model that belongs to Post. I was able to display the Post in the home view corresponding to the home controller and home action and the User/show view. Thus, in the home and user views, the posts are listed in order of creation time. I was also able to have a post form in both the user and home views and a comment form in the home and user views.
The problem arises when I try to display the comment underneath each displayed Post in the home and user views. How can I list the comments associate with each post under the post in the home and user views ?
How do I make sure the comments in the databased are listed under the corresponding post ?
Here is my comments controller:
class CommentsController < ApplicationController
def index
@comments =Comment.all.paginate(page: params[:page])
end
def show
@comment = Comment.find(params[:id])
@post = @Comment.post
end
def new
end
def create
@comment = Comment.new(comment_params)
if @comment.save
flash[:success] = "Comment created"
redirect_to :back
else
render 'new'
end
end
def edit
@comment = Comment.find(params[:id])
end
def update
@comment = comment.find(params[:id])
if @comment.update_attributes(comment_params)
flash[:success] = "Comment updated"
redirect_to @comment.post
else
render 'edit'
end
end
def destroy
Comment.find(params[:id]).destroy
flash[:success] = "Comment deleted"
redirect_to users_url
end
private
def comment_params
params.require(:comment).permit(:author_name, :body)
end
end
Here is my home view: app/views/home/home.html.erb:
<% if logged_in? %>
<div class="row">
<aside class="col-md-4">
<section class="user_info">
<%= render 'shared/user_info' %>
</section>
<hr/>
<br/>
<section class="stats">
<%= render 'shared/stats' %>
</section>
<section class="post_form">
<%= render 'shared/post_form' %>
</section>
</aside>
<div class="col-md-8">
<h3>Post Feed</h3>
<%= render 'shared/feed' %>
</div>
</div>
<% else %>
<div class="center jumbotron">
<h1>Welcome to the Unstarv website</h1>
<h2>
Please sign up now to use this site
<%= link_to "Sign Up", signup_path =%>
now.
</h2>
<%= link_to "Sign up now!", signup_path, class: "btn btn-lg btn-primary" %>
</div>
<%= link_to image_tag("rails.png", alt: "unstarv logo"), '#' %>
<% end %>
And here is my home controller:
class HomeController < ApplicationController
def home
if logged_in?
@post = current_user.posts.build
@feed_items = current_user.feed.paginate(page: params[:page])
end
end
def about
end
def privacy
end
def terms
end
end
And here is my Post model, the relevant part:
class Post < ActiveRecord::Base
belongs_to :user
has_many :comments
default_scope -> { order(created_at: :desc) }
mount_uploader :picture, PictureUploader
end
The relevant part of my User model:
class User < ActiveRecord::Base
attr_accessor :remember_token
before_save { self.email = email.downcase }
has_many :posts, dependent: :destroy
has_many :comments
has_many :active_relationships, class_name: "Relationship",
foreign_key: "follower_id",
dependent: :destroy
has_many :passive_relationships, class_name: "Relationship",
foreign_key: "followed_id",
dependent: :destroy
has_many :following, through: :active_relationships, source: :followed
has_many :followers, through: :passive_relationships, source: :follower
validates :username, presence: true, length: { maximum: 50 }
VALID_EMAIL_REGEX = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :email, presence: true, format: { with: VALID_EMAIL_REGEX },
uniqueness: { case_sensitive: false }
has_secure_password
validates :password, length: { minimum: 6 }, allow_blank: true
def feed
following_ids = "SELECT followed_id FROM relationships WHERE follower_id = :user_id"
Post.where("user_id IN (#{following_ids}) OR user_id = :user_id", user_id: id)
end
end
And here is my Comment model:
class Comment < ActiveRecord::Base
belongs_to :post
belongs_to :user
default_scope -> { order(created_at: :desc) }
end
And here is the post controller:
class PostsController < ApplicationController
before_action :logged_in_user, only: [:create, :destroy]
def index
@posts = Post.all
end
def show
@post = Post.find(params[:id])
@comment = Comment.new
@comment.post_id = @post.id
@comments = @post.comments.all
end
def new
@post = Post.new
end
def create
@post = current_user.posts.build(post_params)
if @post.save
flash[:success] = "Post created!"
redirect_to root_url
else
@feed_items = []
render 'home/home'
end
end
def edit
@post = Post.find(params[:id])
end
def update
@post = Post.find(params[:id])
@post.update(post_params)
flash.notice = "Post '#{@post.title}' Updated!"
render 'home/home '
end
def update
@post = Post.find(params[:id])
@post.update(post_params)
flash.notice = "Post '#{@post.title}' Updated!"
redirect_to root_url
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
@post = Post.find(params[:id])
end
# Never trust parameters from the scary internet, only allow the white list through.
def post_params
params.require(:post).permit(:title, :body, :picture)
end
end
Here is my app/views/post/_post.html.erb file,
<li id="post-<%= post.id %>">
<span class="user"><%= link_to post.user.username, post.user %></span>
<span class="content">
<%= post.title %>
<%= post.body %>
<%= image_tag post.picture.url if post.picture? %>
</span>
<span class="timestamp">
Posted <%= time_ago_in_words(post.created_at) %> ago.
<% if current_user?(post.user) %>
<%= link_to "delete", post, method: :delete,
data: { confirm: "You sure?" } %>
<% end %>
</span>
<section>
<h2>Your Comments here</h2>
<h3>Post a Comment</h3>
<h3>Post a Comment</h3>
<%= render 'shared/comment_form' %>
<% post.comments.all.each do |comment| %>
<h4><small>Comment by</small> <%= comment.post.user.username %></h4>
<p class="comment"><%= comment.body %></p>
<p><small>Posted <%= distance_of_time_in_words(Time.now, comment.created_at) %> ago</small></p>
<br/>
<%end%>
</li>
And here is my app/views/shared/comment_form_html.erb , which works fine:
<%= form_for [ post, post.comments.build] do |f| %>
<p>
<%= f.label :body, "Your Comment" %><br/>
<%= f.text_area :body %>
</p>
<p>
<%= f.submit 'Submit' . method="post", class: 'btn btn-primary' %>
</p>
<% end %>
Here is my app/views/posts/_post.html.erb
<li id="post-<%= post.id %>">
<span class="user"><%= link_to post.user.username, post.user %></span>
<span class="content">
<%= post.title %>
<%= post.body %>
<%= image_tag post.picture.url if post.picture? %>
</span>
<span class="timestamp">
Posted <%= time_ago_in_words(post.created_at) %> ago.
<% if current_user?(post.user) %>
<%= link_to "delete", post, method: :delete,
data: { confirm: "You sure?" } %>
<% end %>
</span>
<h2>Comments</h2>
<h3>Post a Comment</h3>
<%= render 'shared/comment_form', post: post %>
<h3>Comments (<%= post.comments.size %>)</h3>
<% post.comments.each do |comment| %>
<h4><small>Comment by</small> <%= comment.post.user.username %></h4>
<p class="comment"><%= comment.body %></p>
<p>Posted <%= distance_of_time_in_words(Time.now, comment.created_at) %> ago</p>
</li>
<br/>
<%end%>
Thanks a lot for your help !!!!
The issue is related in how you are creating the comments.
With the actual code, the comment does not belong to any post so in your
comments_controller
changecreate
action to something like: