Alexander Donets
Alexander Donets

Reputation: 637

Rails 4: How do I delete a nested object?

So I have a user model and a nested model "Entries" like that:

user.rb

class User < ActiveRecord::Base

  has_many :entries
  ...

end

entry.rb

class Entry < ActiveRecord::Base

  belongs_to :user
  ...

end

user/show.html.erb

<p><%= link_to 'Destroy', remove_entry_path, method: :delete, data: { confirm: 'Are you sure?' } %></p>

routes.rb

resources :users do
    resources :entries
end
...
delete "remove_entry" => "entries#destroy", :as => "remove_entry"

entries_controller.rb

def destroy

    @user = current_user
    @user.entries.find(params[:id]).destroy

    respond_to do |format|
      format.html { redirect_to user_path(current_user), notice: 'Entry was successfully destroyed.' }
      format.json { head :no_content }
    end

  end

And I get this error:

Couldn't find Entry without an ID

on this line

@user.entries.find(params[:id]).destroy

What am I doing wrong?

Upvotes: 1

Views: 690

Answers (2)

user2536065
user2536065

Reputation:

You need to pass an id to this route:

delete "remove_entry" => "entries#destroy", :as => "remove_entry"

The remove_entry route, doesn't have a positional parameter for id, and in your call to remove_entry_path, you don't provide an id param.

That is why in your controller action, params[:id] == nil

Solution

Pass an id

<p><%= link_to 'Destroy', remove_entry_path(id: @entry.id), method: :delete, data: { confirm: 'Are you sure?' } %></p>

or add a positional parameter in the route and pass the id to the url helper.

# config/routes.rb
delete "remove_entry/:id" => "entries#destroy", :as => "remove_entry"

and

<!-- in view -->
<p><%= link_to 'Destroy', remove_entry_path(id: @entry.id), method: :delete, data: { confirm: 'Are you sure?' } %></p>

Upvotes: 1

Deepak Mahakale
Deepak Mahakale

Reputation: 23661

You are receiving params[:id] as nil and that's why you are getting this error

Couldn't find Entry without an ID

Pass @entry object with the route helper

<p><%= link_to 'Destroy', remove_entry_path(@entry), method: :delete, data: { confirm: 'Are you sure?' } %></p>

Upvotes: 0

Related Questions