Reputation: 89
I render a set of checkboxes and I want to delete all the Privilege
of a User
.
I have searched all the questions related, but unluckily none works.
Rails 5.2.3
User
has_many :user_privileges, class_name: 'UserPrivileges'
has_many :privileges, through: :user_privileges
Privilege
has_many :user_privileges, class_name: 'UserPrivileges'
has_many :users, through: :user_privileges
UserPrivileges
belongs_to :user
belongs_to :privilege
The issue kick in when I want to delete ( uncheck ) the last privilege-record of that user in the join_table.
The record is still there, and there is no way to delete/destroy that specific record.
My intuition recall to the callbacks, I have tried different ways of using dependent
but the last record is still there.
Any tips are welcome.
Thanks
Upvotes: 1
Views: 1935
Reputation: 4709
If you want to delete the record from the join table, you need to add dependent: :destroy
to has_many :through
relationship.
# privilege.rb
has_many :user_privileges, class_name: 'UserPrivileges'
has_many :users, through: :user_privileges, dependent: :destroy
See What gets deleted? in API docs:
There is a potential pitfall here: has_and_belongs_to_many and has_many :through associations have records in join tables, as well as the associated records. So when we call one of these deletion methods, what exactly should be deleted?
The answer is that it is assumed that deletion on an association is about removing the link between the owner and the associated object(s), rather than necessarily the associated objects themselves. So with has_and_belongs_to_many and has_many :through, the join records will be deleted, but the associated records won't.
To run dependent: :destroy
callback, you must use the destroy
or destroy_all
method when deleting the privilege record.
See Delete or destroy? in API docs:
For has_many, destroy and destroy_all will always call the destroy method of the record(s) being removed so that callbacks are run. However delete and delete_all will either do the deletion according to the strategy specified by the :dependent option, or if no :dependent option is given, then it will follow the default strategy. The default strategy is to do nothing (leave the foreign keys with the parent ids set), except for has_many :through, where the default strategy is delete_all (delete the join records, without running their callbacks).
Upvotes: 1