Rails 5.1.: destroy records in “has_many: through” association with restriction

冷暖自知 提交于 2019-12-08 04:41:01

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!