57

I have 2 models as describes below.

class EmpGroup < ActiveRecord::Base
  belongs_to :user
  has_many :emp_group_members, dependent: :destroy
end

and

class EmpGroupMember < ActiveRecord::Base
  belongs_to :emp_group
  belongs_to :user
end

now the problem is whenever I tried to destroy a group then I received a error as below.

PG::ForeignKeyViolation: ERROR:  update or delete on table "emp_groups" violates foreign key constraint "fk_rails_bd68440021" on table "emp_group_members"
DETAIL:  Key (id)=(1) is still referenced from table "emp_group_members".

What I'm missing?

Promise Preston
  • 24,334
  • 12
  • 145
  • 143
sank
  • 964
  • 3
  • 12
  • 24

5 Answers5

56

Add cascading delete to your EmpGroup model:

class EmpGroup < ActiveRecord::Base
   has_many :emp_group_members, dependent: :delete_all
end

Or

Are you calling delete method? you should call destroy instead. Use .destroy

Ri1a
  • 737
  • 9
  • 26
Umar Khan
  • 1,381
  • 11
  • 18
  • 3
    Note: Using destroy instead of delete is very important because in case the belonging model (in this case: emp_group_member) has further associations or in any case, the destroy method of emp_group_member will not be called and deleting will simply remove the 1st child. If you want the destroy to be cascading till end, add dependent: :destroy. @Milind 's answer is quite helpful in understanding this point. – ARK Dec 16 '19 at 13:46
  • This value `:delete_all` isn't allowed anymore. – Mark Swardstrom Jul 21 '23 at 21:20
31

:dependent is one of the options available in belongs_to association

If you set the :dependent option to:

:destroy, when the object is destroyed, destroy will be called on its associated objects.
:delete, when the object is destroyed, all its associated objects will be deleted directly from the database without calling their destroy method.

Additionally, objects will be destroyed if they're associated with dependent: :destroy, and deleted if they're associated with dependent: :delete_all.

in has_many associations:

:destroy causes all the associated objects to also be destroyed
:delete_all causes all the associated objects to be deleted directly from the database (so callbacks will not execute)

you can try

 emp_member_1= @emp_group.emp_group_members.first
 ##delete associated record
 @emp_group.emp_group_members.delete(emp_member_1)
Milind
  • 4,535
  • 2
  • 26
  • 58
  • 3
    From the documentation: "You should not specify this option on a belongs_to association that is connected with a has_many association on the other class. Doing so can lead to orphaned records in your database." (https://guides.rubyonrails.org/association_basics.html#options-for-belongs-to-dependent) – BenKoshy Sep 27 '18 at 02:09
  • Sure, that's in the documentation, but what does it MEAN? – Andrew Koster Sep 12 '19 at 18:15
  • They're warning us not to do... something. But it's not clear what that something is. Do I put the `dependent: destroy` on the has_many side, or on the belongs_to side? The whole point of this option is to avoid orphaned records, so why does one of the usages of it cause orphaned records? – Andrew Koster Sep 12 '19 at 18:16
  • @AndrewKoster, this is the warning -> Doing so can lead to orphaned records in your database -- that means you might delete user but user has_many friends will still be there in the db, thereby creating inconsistencies to hunt to one fine day :).So Logically , if user has_many friends, then along with the user , his friends records should also get deleted, where the above :dependent comes into picture.Hope its clear now. – Milind Sep 13 '19 at 22:17
  • 1
    The part I don't understand is why they're saying not to use `dependent: destroy` on the belongs_to side. Why do they allow it as an option, if it doesn't work? – Andrew Koster Sep 14 '19 at 04:05
  • Because deleting has_many wont have any impact on belongs-to but deleting belongs-to would leave has_many orphaned in db. Hence they say it this way. – Milind Sep 14 '19 at 20:57
17

New syntax:

class EmpGroup < ActiveRecord::Base
   has_many :emp_group_members, dependent: :destroy
end
Thomas Van Holder
  • 1,137
  • 9
  • 12
1

When you delete a group, are you using delete or destroy. - I've had this error before, and it was because I had a typo and was using .delete instead of .destroy

abbott567
  • 862
  • 6
  • 18
0

Insert relation like this

has_many :children, :dependent => :destroy

To learn more about destroy and delete, go to this link https://medium.com/@wkhearn/delete-vs-destroy-does-it-even-matter-8cb4db6aa660

Prasanga Thapaliya
  • 657
  • 1
  • 8
  • 19