ERROR: delete on table violates foreign key constraint. Key id is still referenced from table (many)

I'm working with Rails and PostgreSQL and have a basic one-to-many relationship going on, one Auction has many Bids. However when I try and delete an auction (that has bids present) I get the following error:

ERROR: update or delete on table "auctions" violates foreign key constraint "fk_rails_43e9021cbf" on table "bids". DETAIL: Key(id)=(1) is still referenced from table "bids".

Deleting auctions with no bids gives no error.

The part that confuses me is that inside my Auction model, I have:

has_many :bids, dependent: :destroy

Error Screen Shot (better_error gem)

Since I have a dependent destroy clause, why am I still getting this error?

EDIT: I've tried dropping the whole DB, then recreating/re-migrating everything - still get the same error.


Solution 1:

From Rails v4.2 you can do this:

Create a migration to update the foreign keys

20160321165946_update_foreign_key.rb

class UpdateForeignKey < ActiveRecord::Migration
  def change
    # remove the old foreign_key
    remove_foreign_key :posts, :users

    # add the new foreign_key
    add_foreign_key :posts, :users, on_delete: :cascade
  end
end

Solution 2:

Are you using delete or destroy to remove the objects? I think you are using delete and you want to use destroy

See http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#module-ActiveRecord::Associations::ClassMethods-label-Delete+or+destroy-3F

Solution 3:

My issue was that i am using @auction.delete (visible in the screenshot I posted) when trying to remove a record.

Delete will ignore any callbacks I have in place. So even though I have a dependent destroy clause, it is not being called - hence Rails is throwing an error. If/When I changed the code to read @auction.destroy, the call-back got invoked and it solved the problem.

Reference: Difference between Destroy and Delete

Solution 4:

Are you by chance using the paranoia gem or something like it?

If you are bids are paranoid and auctions are not, you may run into this error.

This would happen because when rails executes the dependent: destroy, it would soft-deletes the bids, but they still actually exist in the DB (they just have the deleted_at column set). Therefore, the foreign key constraint would fail.

Solution 5:

Your error is from the database not rails. You need to delete the bids first in your app or change the foreign key constraint in the db to cascade the delete