问题
I have classic has_many: through relationship:
class UserGroup < ApplicationRecord
has_many :user_groups_users
has_many :users, through: :user_groups_users
end
class UserGroupsUser < ApplicationRecord
belongs_to :user_group
belongs_to :user
end
class User < ApplicationRecord
has_many :user_groups_users
has_many :user_groups, through: :user_groups_users
end
and in order to destroy UserGroup record, I need to destroy appropriate records in UserGroupsUser, which both is part of a gem. Otherwise I will get back error that there are Users tied to UserGroups and I cannot destroy particular UserGroup.
At the moment in my Controller I have this:
def destroy
@user_group = UserGroup.find(params[:id])
UserGroupsUser.where(user_group_id: @user_group).destroy_all
respond_to do |format|
if @user_group.destroy
format.js { flash.now[:notice] = "User group #{@user_group.name} deleted!" }
format.html { redirect_to user_groups_url }
format.json { head :no_content }
else
format.js { flash[:danger] = "User group #{@user_group.name} cannot be deleted because
#{@user_group.users.size} users belong to it" }
end
end
end
however when I click Delete button in View, it destroys a record before I accept that in my modal window. How do I make it do destroy action, after accept in view, please? As I undestand it would require that after accept, it would firs destroy records in through models and then UserGroup.
My "Delete" action in View is quite regular:
<%= link_to 'Delete', user_group, method: :delete, remote: true,
data: { confirm: "Do you confirm deleting #{user_group.name}?" }, class: 'btn-danger btn btn-xs' %>
回答1:
To simplify the whole thing, you could just add a before_destroy callback to your UserGroup. It'll only execute when you run @user_group.destroy
class UserGroup < ApplicationRecord
has_many :user_groups_users
has_many :users, through: :user_groups_users
before_destroy do
user_groups_users.destroy_all
end
end
Read ActiveRecord Callbacks
回答2:
Just change has_many :user_groups_users to has_many :user_groups_users, :dependent => :destroy
See more at Association Basics.
Edit: You said it was in a gem. Not an issue, still! Find the class, and add this in an initializer (I know, I know, there are better places, but for the sake of moving on from this):
Whatever::To::UserGroupThing.class_eval do
has_many :user_group_users, :dependent => :destroy
end
But maintenance may not be your friend here if there's some sort of change to the association made down the line by the maintainer.
You could also use a before_destroy hook in user_group.rb
before_destroy do
UserGroupUser.where(:user_group => self).destroy_all
end
来源:https://stackoverflow.com/questions/44350985/rails-5-1-destroy-records-in-has-many-through-association-with-restriction