Reputation: 5629
I want to delete something from my database. The value references some other tables.
Error is:
Mysql2::Error: Cannot delete or update a parent row: a foreign key constraint fails
How can I resolve this properly?
If I add some constraints like on delete cascade the other values won't be deleted right?
Edit:
def delete
@vid = Movie.find params[:id]
@vid.delete
redirect_to :action => :add
end
Update Models
movie.rb
class Movie < ActiveRecord::Base
has_many :comments, :dependent => :destroy
has_many :ratings
belongs_to :channel
has_and_belongs_to_many :tags
has_and_belongs_to_many :categories
mount_uploader :video, MovieUploader
comment.rb
class Comment < ActiveRecord::Base
belongs_to :movie
belongs_to :user
belongs_to :rating
Upvotes: 13
Views: 18634
Reputation: 39
Error: Mysql2::Error: Cannot delete or update a parent row: a foreign key constraint fails
Solution:
I think you have used .delete or delete_all,
Instead of .delete or delete_all use .destroy
.destroy will delete all associated values with that model
Upvotes: 4
Reputation: 3532
If you've created the foreign keys using ActiveRecord::Migration
, it'll use ON DELETE RESTRICT
by default (i.e, the opposite of what you want: row entry will be NOT deleted if there are entries with references from other tables).
You need to change your migration to use ON DELETE CASCADE
:
class CreateChild < ActiveRecord::Migration
def change
create_table :child do |t|
t.references :parent, foreign_key: {on_delete: :cascade}
end
end
end
Upvotes: 12
Reputation: 10777
You are using delete
, from the documentation:
To enforce the object's before_destroy and after_destroy callbacks or any :dependent association options, use #destroy.
So you need to use destroy
instead so that the proper callback from rails to remove dependent records is executed:
def delete
@vid = Movie.find params[:id]
@vid.destroy
redirect_to :action => :add
end
Because your Comment
records depend on the Movie
record that you are trying to delete, hence, since rails is just trying to remove the movie before the comments the database engine complains if there is a foreign key from the comment table to the movie table.
Upvotes: 3
Reputation: 980
Make sure your parent Model.rb has
has_many :model, :dependent => :delete_all
this makes sure all your data gets deleted once you delete a parent Model.
Like for instance you have Post.rb and Comment.rb
Post.rb
has_many :Comments, :dependent => :delete_all
So, When you delete a Post, all corresponding Comments will be deleted as well.
Hope it helped
Cheers
Upvotes: 13
Reputation: 163
Could you post the applicable database schema?
If you set up a delete cascade constraint, then the other values will be deleted. If this isn't the desired outcome, then you might need to rethink the referential integrity of the database.
Perhaps, instead you might want to consider using the ActsAsParanoid gem to soft delete the elements instead?
Upvotes: 1