Reputation: 551
I am trying to follow the following guide for starting Ruby on Rails. Everything went well until I try to destroy (delete comments).
I receive the following error: The action 'show' could not be found for CommentsController
I will post my code below.
http://guides.rubyonrails.org/getting_started.html
comments_controller.rb
class CommentsController < ApplicationController
http_basic_authenticate_with name: "dhh", password: "secret", only: :destroy
def create
@article = Article.find(params[:article_id])
@comment = @article.comments.create(comment_params)
redirect_to article_path(@article)
end
def destroy
@article = Article.find(params[:article_id])
@comment = @article.comments.find(params[:id])
@comment.destroy
redirect_to article_path(@article)
end
private
def comment_params
params.require(:comment).permit(:commenter, :body)
end
end
articles_controller
class ArticlesController < ApplicationController
http_basic_authenticate_with name: "dhh", password: "secret", except: [:index, :show]
def index
@articles = Article.all
end
def show
@article = Article.find(params[:id])
end
def new
@article = Article.new
end
def edit
@article = Article.find(params[:id])
end
def create
@article = Article.new(article_params)
if @article.save
redirect_to @article
else
render 'new'
end
end
def update
@article = Article.find(params[:id])
if @article.update(article_params)
redirect_to @article
else
render 'edit'
end
end
def destroy
@article = Article.find(params[:id])
@article.destroy
redirect_to articles_path
end
private
def article_params
params.require(:article).permit(:title, :text)
end
end
routes.rb
Rails.application.routes.draw do
resources :articles do
resources :comments
end
root 'welcome#index'
end
article.rb
class Article < ActiveRecord::Base
has_many :comments, dependent: :destroy
validates :title, presence: true,
length: { minimum: 5}
end
comment.rb
class Comment < ActiveRecord::Base
belongs_to :article
end
articles/index.html.erb
<h1>Listing Articles</h1>
<%= link_to 'New article', new_article_path %>
<table>
<tr>
<th>Title</th>
<th>Text</th>
<th colspan="3"></th>
</tr>
<% @articles.each do |article| %>
<tr>
<td><%= article.title %></td>
<td><%= article.text %></td>
<td><%= link_to 'Show', article_path(article) %></td>
<td><%= link_to 'Edit', edit_article_path(article) %></td>
<td><%= link_to 'Destroy', article_path(article),
method: :delete,
data: { confirm: 'Are you sure?' } %></td>
</tr>
<% end %>
</table>
Just not sure what it can be. Please advise. I will supply more code if needed.
Upvotes: 1
Views: 18642
Reputation: 51
I ran into same problem but adding
<%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %>
worked for me rails 6 and webpack you should use this
Upvotes: 0
Reputation: 1
I have the same problem and I tried to add this to comments_controller.rb and it works
def show
@article = Article.find(params[:article_id])
@comment = @article.comments.find(params[:id])
@comment.destroy
redirect_to article_path(@article)
end
Upvotes: 0
Reputation: 466
I know this is old, but the tutorial "Getting Started with Rails" is still the top result on Google for those looking to start building web applications using Rails.
I encountered the same issue today and it kind of makes sense. If you want to delete a comment, you can't simply navigate to it with a GET request, you need to use a DELETE method.
I got around this by replacing link_to
with button_to
hoping that Rails would sort out the "magic" and it did.
Code used:
<%= button_to 'Destroy Comment', [comment.article, comment],
method: :delete,
data: { confirm: "Are you sure?" } %>
Instead of
<%= link_to 'Destroy Comment', [comment.article, comment],
method: :delete,
data: { confirm: "Are you sure?" } %>
Upvotes: 4
Reputation: 123
I have had some similar issues, for example:
The action 'show' could not be found for CommentsController
When trying to delete an article, it was not being deleted but rendering its page instead.
The confirmation dialog was not showing when deleting neither an article nor a comment.
I have tried to restart the server as well as one of the solutions above that says to create a show
method identical to the destroy
method. Well, it worked fine for deleting comments but it didn't seem right to me considering the RoR DRY pattern.
I ended up realizing that the browser's extension responsible for blocking JavaScript (NoScript 11.2.9) was active and causing those weird behaviors.
In this special case, it was not related with the Rails itself but external factors.
Upvotes: 0
Reputation: 935
add in comment model belongs_to :user
if you authenticate with user and other too whatever you belongs_to...
Upvotes: 0
Reputation: 41
I've been working through the same tutorial, and just today ran into the exact same issue as the original poster.
I didn't notice exactly when it started, but it seemed to have started somewhere in section 6, 7 or 8 (adding comments to blog, refactoring, or adding deletion of comments).
Furthermore, clicking links within the app (i.e. the 'Back' link) would spawn a new tab. Likewise, when clicking the 'Destroy' link, the browser's confirmation dialog would appear over the current tab (correct behavior), but at the same time a new browser tab would appear (incorrect) - I think this new tab behavior (a type of 'show'ing of the comment that the user is in process of deciding whether to go ahead and destroy) is what was causing the error.
After finishing the tutorial (one more section, basic authentication), I quit & re-launched Chrome, and then also quit & restarted the server (ctrl-c, then bin/rails server).
After doing this, all is well. Both the spawning extra tab behavior, as well as the spurious show action being triggered (thus causing the error) - when the destroy confirmation sheet appears - have stopped.
So it seems that this problem was simply some spurious noise - perhaps caused by something that's changed (in the rails environment?) between the time the tutorial was originally written, and when the original poster ran into this behavior (and still persisting today, July '18, with rails 5.2).
Upvotes: 3
Reputation: 117
You can add
def show
@article = Article.find(params[:article_id])
@comment = @article.comments.find(params[:id])
@comment.destroy
redirect_to article_path(@article)
end
to your comments_controller.rb
Actually these codes are identical to those in the def destroy
Upvotes: 2
Reputation: 1816
Update: As I mentioned earlier you dont have show
method in your CommentsController
so you wont be able to visit the show
page for any comment
.
As you said you are trying to visit this url: localhost:3000/articles/2/comments/1
which is the show page for comment
having id:
1 and the routes(resources :comments
) is trying to take it to show
action. Hence the error rightly thrown show could not be found for CommentsController
.
Please remove the url from your browser and try visiting again the article
show
page. It will work.
Upvotes: -2
Reputation: 8345
The answer will be in your routes.rb and in the URL you are trying to call.
The URL is probably /comment/123
, and the routes.rb likely has something like get 'comment/:id' => 'comment#show'
in it (or a resource
statement for comments).
So rails tries to show the page for a comment and you did not implement the function. The error message is saying exactly what it needs to say (you do indeed not have a .show
method in your CommentsController
).
If my guesses were not correct, then please post your routes.rb and the URL you are requesting.
Upvotes: 7