Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

can't delete object due to foreign key constraint

I'm trying to do a simple user.destroy but running into the following error:

ERROR: update or delete on table "users" violates foreign key constraint "fk_rails_5373344100" on table "identities" DETAIL: Key (id)=(2) is still referenced from table "identities".

Here is my migration for Identities

class CreateIdentities < ActiveRecord::Migration
  def change
    create_table :identities do |t|
      t.references :user, index: true, foreign_key: true
      t.string :provider
      t.string :uid

      t.timestamps null: false
    end
  end
end

Here is my user and identity model:

class Identity < ActiveRecord::Base
  belongs_to :user

  validates_presence_of :uid, :provider
  validates_uniqueness_of :uid, :scope => :provider

  def self.find_for_oauth(auth)
    find_or_create_by(uid: auth.uid, provider: auth.provider)
  end
end

and user:

class User < ActiveRecord::Base
  TEMP_EMAIL_PREFIX = '[email protected]'
  TEMP_EMAIL_REGEX = /\[email protected]/

  # Include default devise modules. Others available are:
  # :lockable, :timeoutable
  devise :database_authenticatable, :registerable, :confirmable,
         :recoverable, :rememberable, :trackable, :validatable, :omniauthable

  validates_format_of :email, :without => TEMP_EMAIL_REGEX, on: :update
...

end

I'm new to foreign keys and references, so I'm not sure at all how to fix this.

like image 271
Ricky Mason Avatar asked Apr 09 '15 17:04

Ricky Mason


People also ask

Can we delete foreign key data?

You can delete a foreign key constraint in SQL Server by using SQL Server Management Studio or Transact-SQL. Deleting a foreign key constraint removes the requirement to enforce referential integrity.

Can we delete primary key without deleting foreign key?

If you want the department to remain and to be able to do this, you will need to alter the foreign key to include ON DELETE SET NULL. Otherwise, you will have to drop the constraint, perform the delete, and recreate the constraint.

What happens if a foreign key is deleted?

When a referenced foreign key is deleted or updated, respectively, the columns of all rows referencing that key will be set to NULL . The column must allow NULL or this update will fail.


2 Answers

You would need to remove the Identity that references the user first. Then you can delete the user.. By default the foreign key is doing a restrict so you cannot delete the user if anything references to it.

if you would like use Rails to handle destroying the identity you can do

class User < ActiveRecord::Base
  has_many :identities,  dependent: :destroy 

  ......

 end 

Which would cause Rails to destroy all the dependent records.

But as you are using Foreign keys, you can adjust your migration to set cascade deletes

 add_foreign_key :identities, :users, on_delete: :cascade

Assuming rails 4.2 which has native support

like image 99
Doon Avatar answered Oct 14 '22 02:10

Doon


An easy solution is to simply cascade-delete the records in the associated table, which can be done through active record, like so:

user.rb

class User < ActiveRecord::Base
  has_many :identities, dependent: :destroy

  # rest of user class
end

Check out the documentation pertaining to has_many for more info.

like image 40
Paul Richter Avatar answered Oct 14 '22 03:10

Paul Richter