Mike Caputo
Mike Caputo

Reputation: 1156

Improperly routed Rails Destroy method on nested resource

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!

Upvotes: 2

Views: 2192

Answers (2)

iwasrobbed
iwasrobbed

Reputation: 46703

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.

Upvotes: 4

andrewpthorp
andrewpthorp

Reputation: 5096

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!

Upvotes: 5

Related Questions