Improperly routed Rails Destroy method on nested resource - ruby-on-rails

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.

Related

Why is the destroy method redirecting incorrectly?

I am working on the destroy functionality for a small rails app. Currently, when I click delete I get the following error:
No route matches [POST] "/note/1"
Here is the relevant controller method:
def destroy
if Note.find(params[:id]).destroy
redirect_to note_index_path, notice: 'Note deleted!'
else
redirect_to note_path, notice: 'Note failed to updated'
end
end
Here is a link example:
<p><%= link_to 'Delete Note', { action: :destroy, id: #note.id }, method: :destroy, data: { confirm: 'Are you sure?' } %></p>
Here are the routes:
Prefix Verb URI Pattern Controller#Action
note_index GET /note(.:format) note#index
POST /note(.:format) note#create
new_note GET /note/new(.:format) note#new
edit_note GET /note/:id/edit(.:format) note#edit
note GET /note/:id(.:format) note#show
PATCH /note/:id(.:format) note#update
PUT /note/:id(.:format) note#update
DELETE /note/:id(.:format) note#destroy
root GET / note#index
You don't need to specify the action in the link_to helper when you make a DESTROY request, try just passing the resource, and specifying the method as delete:
<p><%= link_to 'Delete Note', #note, method: :delete, data: { confirm: 'Are you sure?' } %></p>
The #note object will give you the id, also without having to specify it.
If you make your route wait for a param id like /note/:id, then Rails will take the id value for the object passed as the second parameter in your link_to in this case.

Destroy method in rails and Mongoid

I am trying to delete a particular "work" from an array of "works" which is embedded in user.
In my work.html.erb file in views:-
<% #works.each do |f| %>
<%= link_to 'Destroy', profiles_destroy_path(f), data: {:confirm => 'Are you sure?'}, :method => :delete %>
<% end %>
And in my controller:-
def destroy
#work = current_user.works.find(params[:id])
#work.destroy
respond_to do |format|
format.html { redirect_to root_url }
end
end
I am getting following error:-
Mongoid::Errors::InvalidFind at /profiles/destroy.56fa4d2f498b5908a002e2e8
P.S. - I am new to rails.
Please check params[:id] is not nil. There's no :id at session start and you get the Mongoid::Errors::InvalidFind exception above.
delete action doesn't have path by default..
<%= link_to 'Destroy', profiles_path(f), data: {confirm: 'Are you sure?'}, method: :delete %>
That will call the destroy action from your controller.
And make sure params[:id] is not nil.
PS: use rails 4 annotation (avoid using rockets (=>))
There may be an error in Juan's answer.
I believe you want:
<%= link_to 'Destroy', profile_path(f), method: :delete, data: {confirm: 'Are you sure?'} %>
Note: the singular "profile_path" instead of "profiles_path"
This is because the destroy action uses the same path as the show action, but uses a DELETE method instead of a GET. (Which you can observe by running "rake routes" in your terminal and comparing the two routes.)

Index pagination with links to own method

actually i use the following code in my _user.html.erb:
<%= link_to "Delete User", user, method: :delete, data: { confirm: "Are you sure?" } %>
For every user i get a link to delete him.
In my controller the delete-method calls the destroy-method:
def destroy
User.find(params[:id]).destroy
flash[:success] = "User deleted."
redirect_to users_url
end
This all works fine.
What i want now is another link where a call a custom method.
How can i call a custom method?
What i already tried was to add a method with the name test and then i called method: :test but this doesn't work:
No route matches [POST] "/users/2"
Thanks for any idea
Question heading is wrong, pagination means something else.
First configure your routes like
resources :controller_name do
member do
delete 'test'
end
end
Your route will be set ..
test_controller_name DELETE /controller_name/:id/test(.:format) controller_name#test
Call the action from link_to and pass the object id .
<%= link_to 'Destroy', test_controller_path(:id => #object.id), method: :delete, data: { confirm: 'Are you sure?' } %>

Rails DELETE http method renders page

I am trying to add a delete functionality to my model. This is what I've come up with, but even though I don't need to render the page to delete something, Rails renders and couldn't find the file for "delete.html.erb"
I am using Ruby 2.0dev and Rails 4.0
My delete link:
<%= link_to "Delete", reservation_delete_path(item), :class => "btn btn-small btn-danger", method: :delete, data: {confirm: 'Are you sure?'} %></td>
My routes file:
match 'reservations/delete/:id' => 'reservations#delete', via: :delete, :as => 'reservation_delete'
My Controller:
def delete
#current = Reservations.find(params[:id])
if current_user
if #current.user_id == current_user.id
#current.destroy!
redirect_to reservations_path
else
redirect_to reservations_path
end
else
redirect_to reservations_path
end
end
There is no need to duplicate the redirect 3 times for each condition. You can simplify your delete method:
def delete
#current = Reservations.find(params[:id])
if current_user && #current.user_id == current_user.id
#current.destroy!
end
redirect_to reservations_path
end
In your question, if current_user isn't available, you have no redirect, and so an implicit render is being run.
Your setup is not idiomatic, and there's code you didn't include, so anything could be going wrong. For example, that can't be your whole routes file; there's nothing specifying an index/show/edit/whatever page where your delete button would be. Another example: your action is named delete instead of destroy. Anyway I can show you an example that works and is much more canonical:
models/reservation.rb:
class Reservation < ActiveRecord::Base
end
controllers/reservations_controller.rb:
class ReservationsController < ApplicationController
def index
#reservations = Reservation.all
end
def destroy
#reservation = Reservation.find(params[:id])
#reservation.destroy
redirect_to reservations_url
end
end
views/reservations/index.html.erb:
<% #reservations.each do |reservation| %>
<%= link_to 'Destroy', reservation, method: :delete, data: { confirm: 'Are you sure?' } %>
<% end %>
(this will literally only show links for deleting corresponding reservations... you'll have to stick <%= reservation.name %> or whatever in there if you want to see more info)
config/routes.rb:
Howdy::Application.routes.draw do
resources :reservations, only: [:index, :destroy]
root 'reservations#index'
end
(my app name is howdy)
You have some user auth going on, so add that accordingly. If you're inheriting from a controller that does special user-auth stuff before even hitting the action, that might be why it's trying to render delete.html.erb
Looks like you're missing a return with those redirects, which is actually causing Rails to both execute the redirect and try to render the view.
return redirect_to reservations_path
Two things:
The delete (destroy) action is part of resources when you specify it in the routes file. To do this the "rails" way, you might consider having your routes file look more like:
resources: :reservations, only: [:delete]
... then having the delete link be more like:
<%= link_to 'Delete', delete_reservation_path(item), :class => 'btn btn-small btn-danger', method: :delete, data: {confirm: 'Are you sure?'} %>
... and then in your controller you can:
def destroy
#current = Reservations.find(params[:id])
if current_user
if #current.user_id == current_user.id
#current.destroy!
redirect_to reservations_path
else
redirect_to reservations_path
end
else
redirect_to reservations_path
end
end
... or you could actually create an rjs template for the delete action to do some fancy javascript work, or you could simply render the view for the index action (faster load the redirecting).
My recommendation when you start putting up && gates is to check to see if there is an existing solution. In this case you're probably looking for the functionality that is available in the CanCan gem.
CanCan
basically you load_and_authorize your users before the controller action and check them through an Ability model. You also get view helpers like
if can? :destroy, reservation
... do awesome stuff here ...
This will be a far better solution over the long run.

ROR delete action not working

I am beginner to ROR and I am following this tutorial http://guides.rubyonrails.org/getting_started.html.
So according to this tutorial I want to delete one post. But its not working it showing this error The action 'destroy' could not be found for PostsController
My post controller delete method looks like
def destroy
#post = Post.find(params[:id])
logger.debug "***********************: #{#post.id}"
#post.destroy
redirect_to posts_path
end
In routes I mentioned resource resources :posts but still it is giving error for destroy action. Am I doing something wrong. Need Help.
Did you mention the method as delete in your views?
If you are using Rails 4, you should do:
<%=link_to 'Destroy', post_path(post), method: :delete, data: { confirm: 'Are you sure?' } %>
In Rails 3:
<%=link_to 'Destroy', post_path(post), method: :delete, confirm: 'Are you sure?' %>

Resources