roguerat
roguerat

Reputation: 217

Rails: Couldn't find Comment with 'id'=

I'm trying to add "likes" to "comments", so that a user has the ability to like a comment. When I click on "like" I get an error saying Couldn't find Comment with 'id'= on this line here: comment = Comment.find params[:comment_id] which is in my likes_controller.rb#create.

likes_controller.rb

class LikesController < ApplicationController

  def create
    comment  = Comment.find params[:comment_id]
    like      = comment.likes.new
    like.user = current_user
    if like.save
      redirect_to new_discussion_comment_path, notice: "Liked!"
    else
      redirect_to new_discussion_comment_path, alert: "Liked Already!"
    end
  end

  def destroy
    comment = Comment.find params[:comment_id]
    like    = comment.likes.find params[:id]
    if like.destroy
      redirect_to new_discussion_comment_path, notice: "UnLiked!"
    else
      redirect_to new_discussion_comment_path, alert: "Can't UnLike!"
    end
  end
end

comments_controller.rb

class CommentsController < ApplicationController

  def new
    @discussion = Discussion.find(params[:discussion_id])
    @comment = Comment.new
  end

  def create
    @discussion = Discussion.find(params[:discussion_id])
    @comment = @discussion.comments.build(comment_params)
    if @comment.save
      redirect_to new_discussion_comment_path(@discussion)
    end
  end



  def edit
    @discussion = Discussion.find(params[:discussion_id])
    @comment = @discussion.comments.find(params[:id])
  end

  def update 
    @discussion = Discussion.find(params[:discussion_id])
    @comment = @discussion.comments.find(params[:id])
    if @comment.update_attributes(comment_params)
      redirect_to new_discussion_comment_path
    else
      render "edit"
    end
  end

  def destroy
    @comment = Comment.find(params[:id])
    @comment.destroy
    redirect_to new_discussion_comment_path
  end

  private
  def comment_params
    params.require(:comment).permit(:id, :description)
  end

end

(comments) _form.html.erb

<%= form_for [@discussion, @comment] do |f| %>
  <div class="container">
    <div class="form-group">
      <%= f.label :description %>
      <%= f.text_area :description, class: "form-control" %>
    </div>

    <div class="form-group">
      <%= f.submit "Submit comment", class: "btn btn-primary" %>
    </div>
  </div>
<% end %>

(comments) edit.html.erb

<%= render "form" %>

(comments) new.html.erb

<div class="container">
  <div class="page-header">
    <h1>Comments<small> Create a comment.</small></h1>
  </div>
</div>

Discussion: <%= @discussion.title %> <%= link_to "Go back?", projects_path %>


<%= render "form" %>


<% if [email protected]? %>
  <% for item in @discussion.comments %>
  <div class="container">
  <div class="panel panel-default">
  <div class="panel-heading">
    <%= item.description %>
    <p>
      <%= link_to "Edit", edit_discussion_comment_path(@discussion, item) %> 
    </p>
     <% if user_signed_in? && current_user.has_liked?(item) %>
     <% like = current_user.likes.find_by_comment_id(item.id) %>
      <%= link_to "unlike", discussion_like_path(:discussion_id, item), class: "btn btn-info like  ", method: :delete %>
  <% else %>
      <%= link_to "like", discussion_likes_path(:discussion_id, item), class: "btn btn-info like ", method: :post %>
  <% end %>
  </div>
  </div>
  </div>
  <% end %>
<% end %>

routes:

discussion_comments GET    /discussions/:discussion_id/comments(.:format)          comments#index
                         POST   /discussions/:discussion_id/comments(.:format)          comments#create
  new_discussion_comment GET    /discussions/:discussion_id/comments/new(.:format)      comments#new
 edit_discussion_comment GET    /discussions/:discussion_id/comments/:id/edit(.:format) comments#edit
      discussion_comment GET    /discussions/:discussion_id/comments/:id(.:format)      comments#show
                         PATCH  /discussions/:discussion_id/comments/:id(.:format)      comments#update
                         PUT    /discussions/:discussion_id/comments/:id(.:format)      comments#update
                         DELETE /discussions/:discussion_id/comments/:id(.:format)      comments#destroy
        discussion_likes GET    /discussions/:discussion_id/likes(.:format)             likes#index
                         POST   /discussions/:discussion_id/likes(.:format)             likes#create
     new_discussion_like GET    /discussions/:discussion_id/likes/new(.:format)         likes#new
    edit_discussion_like GET    /discussions/:discussion_id/likes/:id/edit(.:format)    likes#edit
         discussion_like GET    /discussions/:discussion_id/likes/:id(.:format)         likes#show
                         PATCH  /discussions/:discussion_id/likes/:id(.:format)         likes#update
                         PUT    /discussions/:discussion_id/likes/:id(.:format)         likes#update
                         DELETE /discussions/:discussion_id/likes/:id(.:format)         likes#destroy

Upvotes: 1

Views: 1318

Answers (3)

lifus
lifus

Reputation: 8482

This is a bit uncommon:

POST /discussions/:discussion_id/likes(.:format) likes#create

As you can see, there is no :comment_id, you may pass it as a query parameter but still it's not a standard way to do it.


Here's a more standard way to do this:

POST /discussions/:discussion_id/comments/:comment_id/likes(.:format) likes#create

And then you may:

 discussion_comment_likes_path(@discussion, item)

but this isn't great either:

 resources :discussions do
   resources :comments do
     resources :likes, only: [:create, :destroy]
   end
 end

Also, you don't use :discussion_id inside your LikesController anyway


Better yet:

POST /comments/:id/likes(.:format) likes#create

because

Resources should never be nested more than 1 level deep.

resources :discussions do
  resources :comments
end

resources :comments do
  resources :likes, only: [:create, :destroy]
end

and the you may

comment_likes_path(item)

Upvotes: 2

challett
challett

Reputation: 906

I think that the problem lies in that you are not referencing the parameter that you pass to your likes controller.

You can try passing your comment as a hash to your likes_controller.rb by changing:

<%= link_to "like", discussion_likes_path(:discussion_id, item), class: "btn btn-info like ", method: :post %>

to

<%= link_to "like", discussion_likes_path(:discussion_id, :comment_id => item.id), class: "btn btn-info like ", method: :post %>

In your (comments) new.html.erb and referencing this new parameter in your likes_controller.rb with:

comment = Comment.find params[:comment_id]

Upvotes: 0

Martin B.
Martin B.

Reputation: 800

In (comments) new.html.erb, change:

<%= link_to "like", discussion_likes_path(:discussion_id, item), class: "btn btn-info like ", method: :post %>

to

<%= link_to "like", discussion_likes_path(:discussion_id, item.id), class: "btn btn-info like ", method: :post %>

Upvotes: 0

Related Questions