I am creating an application that allows users to make comments on project postings created. I followed this Railscast to set up polymorphic associations.
Everything works great per tutorial, but I have been trying to build in a delete method in my comment controller so comments can be deleted. I created a method in my comments controller called destroy.
Comments are made on my project postings. The partial for the comments are generated on the project pages and on the pages of the users who make the postings. When I delete on the project pages, it works great, but when I try to delete from the user page, I get the result below. How can I fix it so comments can be deleted by users whether they are deleting from the project page or from their own user pages?
Unknown action
The action 'show' could not be found for CommentsController
comments_controller.rb
def destroy
#comment = Comment.find(params[:id])
#comment.destroy
if #comment.destroy
redirect_to #commentable, notice: "Comment deleted."
end
end
_comment.html.erb
<div class="comments">
<p><%= comment.content %></p>
<span>
By <%= link_to comment.user.name, comment.user %> <%= time_ago_in_words(comment.created_at) %> ago
<div class="pull-right">
<%= link_to "Destroy", [#commentable, comment], method: :delete, data: { confirm: 'Are you sure?' } %>
</div>
</span>
</div>
routes.rb
resources :comments
resources :projects do
resources :comments
member do
get :following
end
end
Try this...
<%= link_to "Destroy", [#commentable, comment], method: :delete, data: { confirm: 'Are you sure?' } %>
Related
I would like to convert this line of code into a link that goes to the destroy route in my routes table. When this picture is pressed it will delete the current photo.
<%= image_tag #user.avatar.avatarpic %>
The route is as follows:
user_avatar DELETE /users/:user_id/avatars/:id(.:format) avatars#destroy
The Avatar controller is as follow:
class AvatarsController < ApplicationController
def create
#user = User.find(params[:user_id])
#avatar = Avatar.new(avatar_params)
#avatar.user = #user
#avatar.save
# Three lines above can be replaced with
# #user.create_avatar(params)
redirect_to user_path(#user)
end
private
def avatar_params
params.require(:avatar).permit(:avatarpic)
end
end
Currently I have an if/else statement that will display a default image if an avatar photo isn't available:
<% if #user.avatar.present? %>
<%= image_tag #user.avatar.avatarpic %>
<% else %>
<%= image_tag 'user.png' %>
<a href="#" class="add-image" data-toggle="modal" data-
target="#avatarpic">
Add a Picture
</a>
<% end %>
I would also like for a message to display once the mouse is hovering over the current avatar photo. It will say something to the effect of "Upload a different image". Once pressed, there should be a warning that asks the user "Are you sure you would like to delete this image?". Thank you for your help.
Following the route you give above, please try this:
<%= link_to user_avatar_path, method: :delete, data: { confirm: 'Are you sure' } do %>
<%= image_tag #user.avatar.avatarpic %>
<% end %>
I'm not in front of my PC but this should work:
<%= link_to destroy_path, method: :delete, data: { confirm: 'Are you sure?' } do %>
<%= image_tag #user.avatar.avatarpic %>
<% end %>
Please try and let me know if it does.
Edited to include config/routes.rb file.
I'm working through the Jumpstartlab Blogger 2 tutorial and I've run into trouble trying to delete tags from a tag list. This is my first Rails project and I'm still trying to wrap my head around MVC and routing.
Here's the code from my Tags view:
<h1>All Tags</h1>
<ul id="tags">
<% #tags.each do |tag| %>
<li>
<%= link_to tag.name, tag_path(tag), class: 'tag_name' %>
<%= link_to "Delete", tags_path(#tag), method: :delete, data: {confirm: "Really delete the tag?"} %>
</li>
<% end %>
</ul>
And the code from my Tags controller:
class TagsController < ApplicationController
def show
#tag = Tag.find(params[:id])
end
def index
#tags = Tag.all
end
def destroy
#tag = Tag.find(params[:id])
#tag.destroy
end
end
And config.routes.rb:
Blogger::Application.routes.draw do
root to: 'articles#index'
resources :articles do
resources :comments
end
resources :tags
end
The error I'm getting is No route matches [DELETE] "/tags".
I feel like the issue is something basic that I haven't quite grasped yet. I would really appreciate if someone could help me understand what I've missed and how it works. If I haven't provided enough information, please let me know. And thanks!
It's because the DELETE route is based on an instance (just 1 tag) of a resource, not the collection (the group of tags).
So you have to change this line:
<%= link_to "Delete", tags_path(#tag), method: :delete, data: {confirm: "Really delete the tag?"} %>
To use tag_path(tag):
<%= link_to "Delete", tag_path(tag), method: :delete, data: {confirm: "Really delete the tag?"} %>
I'm trying to create a form_for that will accept the current_users password in order to delete one of their projects. Basically the process of deletion doesn't need to know anything about that user. just the confirmation step of ensuring that they intend to delete the project. What should my form look like? It doesn't have to be form_for it can be form_tag too.
Current View:
<div class="modal">
<h2>Confirm Project Deletion</h2>
<%= form_for #user, url: new_account_path, method: :delete, do |f| %>
<%= f.submit %>
<% end %>
</div>
I also have access to #project which has the current_project attached to it as well as current_user as you can see. Any help would be great thanks.
A fairly common approach would be to use a delete tag on the index page of all projects, like this:
<% #projects.each do |project| %>
<%= project.title %>
...
<% if current_user.id == project.user_id %>
<%= link_to project, method: :delete, data: { confirm: 'This will delete this project.' } do %>
Delete!
<% end %>
<% end %>
If only the project user can view only his projects on the index page, then just use the link_to method: :delete because the user is already authenticated.
Assuming you have a local variable project in your page and have a route such as:
project DELETE /projects/:id(.:format) projects#destroy
then you can simply set up a form such as
<%= form_tag project_path(id: project.id), method: :delete do %>
<%= label_tag :password %>
<%= password_field_tag 'password', '' %>
<input value='Delete Project' type='submit' id='submit-form'/>
<% end %>
All you then need to do is add your authentication check in to the destroy method:
def destroy
project = Project.find(params[:id])
password = params[:password]
# Do my authentication check here
if #project and authenticated
#project.destroy
respond_to do |format|
format.html { redirect_to projects_url, notice: 'Project was successfully destroyed.' }
end
end
end
Personally though, I think it would be much better if you implemented a resource based authorisation mechanism, such as CanCanCan, which would work alongside your authentication system. This would enable you to set abilities (rules) that would ensure that the current_user can only view / delete / manage their own projects, without requiring them to authenticate every time they wish to destroy a resource.
I am new to RoR and still don't have enough experience on solving the different errors that may appear to me. In this case I am designing a blog where I can post articles. More specifically, my problem is related to deleting these articles.
As far as I know, writing:
resources :articles
in the routes file is an alternative for writing:
get "/articles" #index
post "/articles" #create
delete "/articles/:id" #delete
get "/articles/:id" #show
get "/articles/new" #new
get "/articles/:id/edit" #edit
patch "/articles/:id" #update
put "/articles/:id" #update
When I try to delete an article I get the following error:
No route matches [POST] "/articles/1"
The code I wrote was:
View
<% #articles.each do |art| %>
<%= art.title %>
<div>
<%= art.body %> - <%= link_to "Delete", art, method: :delete %>
</div>
<% end %>
Controller
def destroy
#article = Article.find(params[:id])
#article.destroy
redirect_to articles_path
end
It sounds like you have this in your view:
<%= art.body %> - <%= link_to "Delete", art, method: :destroy %>
But you actually need:
<%= art.body %> - <%= link_to "Delete", art, method: :delete %>
I'd advise double-checking this in your app based on your reply to a comment from #GonzaloRobaina.
It looks to me like you're missing the correct path in your code. It should work with something like this :)
<%= link_to "Delete, article_path(art), method: :delete %>
I have a List object, with nested Tasks. I have created a page that displays individual tasks, and also a page that allows a user to edit individual tasks. I now want to add the ability to delete a task from a list on the tasks edit page. Using the following code
<%= link_to 'Delete this task',#task, confirm: 'Are you sure?', method: :delete %>
yields
undefined task_path method
This code is on the show.html.erb page, where I call #task to display all of the data stored within the task, so I believe that this issue may be a routing error of some kind, however I cannot seem to figure it out.
The related controller method is
def destroy
#task = Task.find(params[:id])
#task.destroy
respond_to do |format|
format.html { redirect_to list_tasks_path(#task) }
format.json { head :ok }
end
end
I thought that with the delete method the #task I supplied would just be sent to the destroy method via params, but this error seems to be showing that this isn't exactly how it works. So how can I properly destroy a nested resource in Rails?
edit:
Here is the route file with nested resources:
MyApp::Application.routes.draw do
resources :lists do
resources :tasks
end
get "home/index"
root :to => 'home#index'
end
Thank you for your help!
You should have #list setup, or use #task.list (assuming you have a belong to relationship), and you could do the following:
<%= link_to "Delete this task", list_task_path(#task.list, #task), confirm: "Are you sure?", method: :delete %>
Cheers!
Try this:
<%= link_to 'Delete this task', list_task_path(#list, #task), confirm: 'Are you sure?', method: :delete %>
Or if you want it more compact (like you've written it):
<%= link_to 'Delete this task', [#list, #task], confirm: 'Are you sure?', method: :delete %>
Either way, since it's a nested resource, you must pass in both the #list and #task objects.