2

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' %>
matiss
  • 747
  • 15
  • 36

2 Answers2

0

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
Amin Shah Gilani
  • 8,675
  • 5
  • 37
  • 79
Josh Brody
  • 5,153
  • 1
  • 14
  • 25
  • I know this, however I can't do it as `UserGroupsUser` model is in gem. Is there any other way to achieve this? – matiss Jun 04 '17 at 05:46
  • Thank you. Does that second solution would go into my Controller, right? First one is quite tricky, because as you said - gem's maintainer may change something in the Model. – matiss Jun 04 '17 at 06:10
  • Gets thrown into your user_group.rb model. – Josh Brody Jun 04 '17 at 06:38
  • Thank you, probably this would work,however I can't modify anything but `User` model. I think I'll do it from different angle. I will allow `current_user` to untie all users from particular user group and then if there is no users in particular group, I'll automatically delete that group. I could even throw warning for `current_user` that it is last user for the group and if there is no user in group, it will be deleted. I don't want to keep any unused items in my DB. In addition this will keep preventing of situation when some user appears to loose any group and basically can't do anything. – matiss Jun 04 '17 at 16:48
0

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

Amin Shah Gilani
  • 8,675
  • 5
  • 37
  • 79
  • Since the Model is in gem, I can't modify it. All of my custom modifications have to be done in my Controller. Can I do something similar there, please? – matiss Jun 04 '17 at 06:06
  • @matiss which gem? – Amin Shah Gilani Jun 04 '17 at 06:10
  • It's [Strongbolt](https://github.com/605data/strongbolt) where I'm implementing functionality which allows create custom User Groups for `current_user`. – matiss Jun 04 '17 at 06:12
  • Basically at the moment there is this `:dependent => :restrict_with_exception` in the Model and I cannot modify that. – matiss Jun 04 '17 at 06:18