Alexander Donets Alexander Donets - 13 days ago 8
Ruby Question

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?

Answer

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>