In my Rails app, each post has a comment section where users can leave comments. I want each comment to have a delete link but I just can't get it to work. I am using the acts_as_commentable gem here.
posts/show.html.erb
<% #comments.each do |comment| %>
<p><strong><%= comment.user.username %></strong></p>
<p class="comment"><%= comment.comment %><p>
<%= link_to "Delete", [#post, comment], method: :delete %>
<% end %>
I need help with this line
<%= link_to("Delete", [#post, comment], method: :delete %>
comments_controller.rb
def create
#post = Post.find(params[:post_id])
#comment = #post.comments.create(comment_params)
#comment.user_id = current_user.id
end
def destroy
#comment = Comment.find(params[:id])
redirect_to :back
end
Thanks for your help! :)
You are not destroying it at all in the destroy action, you need to add #comment.destroy to delete the comment from database
def destroy
#comment = Comment.find(params[:id]
#comment.destroy # add this line
redirect_to :back
end
Hope that helps!
change destroy action something like this:
def destroy
#post = Post.find(params[:post_id])
#comment = #post.comments.find(params[:id])
#comment.destroy
redirect_to :back
end
In this way you can make sure you are deleting comment related to specific post. It's rails proffered way you can look at it here .
Related
I'm currently working on a project involving users, likes, and posts. I have a like/unlike button that I finally got to work some of the time, but on certain user's profiles when I go to unlike a post, I get thrown this error, which says that it is coming from my destroy action in my likes controller:
ActionController::InvalidAuthenticityToken
I'm using devise, but don't know if that has to do with the cause of the issue.
Right now this is what I'm working with:
<h4>All of <%= #user.email %>'s posts:</h4>
<% #user.posts.order('created_at DESC').each do |post| %>
<li><%= post.content %></li>
<% unless current_user.likes.pluck(:post_id).include?(post.id) %>
<%= form_tag likes_path do %>
<%= hidden_field_tag 'post_id', post.id %>
<%= submit_tag "Like", :class => "like_button" %>
<% end %>
<% else %>
<% like = post.likes.where(user_id: current_user.id).first %>
<div class="unlike_button">
<%= form_tag like_path(like) do %>
<%= hidden_field_tag 'post_id', post.id %>
<%= button_to "Unlike", like_path(post), method: :delete %>
</div>
<% end %>
class LikesController < ApplicationController
def create
#post = Post.find(params[:post_id])
#like = Like.new(user_id: current_user.id, post_id: #post.id)
if #like.save
flash[:success] = "Post Liked!"
redirect_back(fallback_location: root_path)
else
flash[:notice] = "Couldn't like post"
redirect_back(fallback_location: root_path)
end
end
def destroy
#like = Like.find(params[:id])
#like.destroy
flash[:success] = "Post unliked"
redirect_back(fallback_location: root_path)
end
end
class PostsController < ApplicationController
def index
#posts = Post.all
#user = User.find(params[:user_id])
end
def new
#post = Post.new
#user = User.find(params[:user_id])
end
def create
#post = current_user.posts.build(post_params)
if #post.save
flash[:success] = "Posted!"
redirect_to user_path(current_user)
else
flash[:notice] = "Post could not be submitted"
redirect_to users_path
end
end
private
def post_params
params.require(:post).permit(:content)
end
end
There is a comment in application_controller.rb..
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
so ,you may try changing..
protect_from_forgery with: :exception
to this
protect_from_forgery with: :null_session
Hope it helps :)
I think I have figured it out.. At least have gotten it to work. I wasusing a form_for helper as well as button_to helper. I deleted the form_for helper and just stuck with
<%= button_to "Unlike", like_path(like), method: :delete %>
and it is now working
What helps me solve this problem is adding the Forward Slash in the URL
From:
= bootstrap_form_tag url: 'signup_with_phone' do |form|
To:
= bootstrap_form_tag url: '/signup_with_phone' do |form|
I made a ruby on rails blog as part of my project. I wanted to add comments to my blog. However, the site takes the comment and stores it successfully but when it comes to showing the comments, it doesn't work. I checked if the comment was registered using the rails console and it is registered. The github repository for it is : https://github.com/rocka0/blog-in-rails
Note: If specific code is needed, please let me know in the comments
https://github.com/rocka0/blog-in-rails/blob/master/app/views/posts/_comments.html.erb#L1
I think it should be:
<%= div_for #comments do |comment| %>
I'm a bit surprised it does not throw any error here.
Edit: You also don't set #comments instance variable anywhere in the controller: https://github.com/rocka0/blog-in-rails/blob/master/app/controllers/posts_controller.rb#L13 You should do it or use #post.comments instead.
In the _comments.html.erb
<%= div_for #comments do |comment| %>
<p>
<strong>
Posted <%= time_ago_in_words(comment.created_at) %> ago
</strong>
<br/>
<%= comment.body %>
</p>
<% end %>
In the posts_controller.rb
........
def show
#comments = #post.comments
respond_with(#comments)
end
Check Your Comments Controller
class CommentsController < ApplicationController
def create
#post = Post.find(params[:post_id])
#comment = #post.comments.create(params[:comment].permit(:name, :body))
redirect_to post_path(#post)
end
def destroy
#post = Post.find(params[:post_id])
#comment = #post.comments.find(params[:id])
#comment.destroy
redirect_to post_path(#post)
end
end
To me this is a strange one.
I have 2 models (with User), I have post and I have comment.
What I am trying to do is to have the form_for comments in the post#show view.
However for some reason when I try to create a comment I get Couldn't find Post without an ID.
When I look at the request parameters though I see:
{"utf8"=>"✓", "authenticity_token"=>"7bAXF66sghTKAF7b61gu08hElC+O1nR6RoT92tqQGOI=", "comment"=>{"content"=>"ok"}, "commit"=>"Add comment", "action"=>"create", "controller"=>"comments", "post_id"=>"23"}
which clearly shows that it does in-fact get the post_id and that it is in this case the id of 23.
After countless hours I thought that I'd see if you guys have a solution.
My comments_controller.rb:
class CommentsController < ApplicationController
before_action :load_post
def create
#comment = #post.comments.build(params[:content])
#comment.user = current_user
if #comment.save
#comment.create_activity :create, owner: current_user
redirect_to root_url, notice: "Comment was created."
else
render :new
end
def load_post
#post = Post.find(params[:id])
end
end
My posts_controller.rb
def show
#post = Post.find(params[:id])
#comment = Comment.new
end
the partial for the forms comments/_form.rb
<%= form_for [#post, #comment] do |f| %>
<%= f.text_area :content %>
<%= f.submit "Add comment" %>
<% end %>
My routes.rb
resources :posts do
resources :comments
end
my posts/show.html.erb
<%= render #post %>
<h3>New comment</h3>
<%= render 'comments/form' %>
my posts/_post.html.erb
<h2><%= #post.title %></h2>
<p><%= #post.content %></p>
<em>written by <%= #post.user.fullname %></em>
You are receiving "post_id" not as "id"
You can make load_post action as private for security concerns
private
def load_post
#post = Post.find(params[:post_id])
end
Access the content like
def create
#comment = #post.comments.build(params[:comment][:content])
....
I am getting this error while i am going to delete a comment associated with a post.
// my CommentsController
def destroy
#post = Post.find(params[:post_id])
#comments = #post.comments.find(params[:comment])
#comments.destroy
redirect_to post_path(#post)
end
// my form::
<p>
<strong><%= comment.commenter %>: </strong>
<%= comment.body %>
<strong> at </strong><%= comment.created_at %>
<%= link_to 'Delete Comments', [comment.post,comment], method: :delete, data: {confirm: 'Are you Sure'} %>
</p>
I am getting the error in ::
#comments = #post.comments.find(params[:comment])
please tell me where i am wrong..
You probably should have:
#comment = #post.comments.find(params[:id])
#comment.destroy
Since by default, nested resource record id is referenced by params[:id] in destroy action.
Use this instead
#post = Post.where(:id => params[:post_id]).first
unless #post.blank?
#comment = #post.comments.where(:id => params[:id]).first
unless #comment.blank?
#comment.destroy
flash[:notice] = "Comment deleted"
redirect_to post_path(#post)
else
flash[:notice] = "Comment not found"
redirect_to post_path(#post)
end
end
The difference between find and where is that, where returns an empty array if no comment is found. But find raise an ActiveRecord::RecordNotFound error. Is it clear? If no comment of that id is present in the table then it will return an empty array, and in second line I have added a condition that if comment is not found don't perform destroy action. I've simply handled the error.
You have to include <%= flash[:notice] %> in view file to see the error/success message
I am trying to write my delete method in my comment controller. My comment model has polymorphic associations with other models but in this case, we'll just focus on trips. In other words, #trip = #commentable.
The comment gets deleted just fine, but I keep getting the error ActionController::ActionControllerError in CommentsController#destroy: Cannot redirect to nil! when I redirect_to #commentable which would be the trip that the comment belonged to.
I also redirected to #commentable in my create action (comment controller) and that works just fine when the user creates a new comment.
Any tips?
view (trips/show.html.erb)
<% if !#commentable.comments.empty? %>
<% #commentable.comments.each do |comment| %>
<!-- Content -->
<%= link_to comment, :method => :delete do %> delete <% end %>
<% end %>
<% end %>
comment form that works for create action
<%= form_for [#commentable, Comment.new] do |f| %>
<%= f.text_area :content %>
<div id="comment_submit_button"><%= f.submit "Comment" %></div>
<% end %>
trips_controller.rb
def show
#trip = #commentable = Trip.find(params[:id])
#comments = Comment.all
end
comments_controller.rb
def create
#commentable = find_commentable
#comment = #commentable.comments.build(params[:comment])
#comment.user_id = current_user.id
if #comment.save
redirect_to #commentable
end
end
def destroy
# #commentable = find_commentable this line was wrong
#comment = Comment.find(params[:id])
#commentable = #comment.commentable #this line fixed it
if #comment.destroy
redirect_to #commentable
end
end
def find_commentable
params.each do |name, value|
if name =~ /(.+)_id$/
return $1.classify.constantize.find(value)
end
end
nil
end
Figured out the solution. Will post solution in code above.
def destroy
#comment = Comment.find(params[:id])
#commentable = #comment.commentable
if #comment.destroy
redirect_to #commentable
end
end