Rails 5.1:销毁" has_many中的记录:通过"与限制的关联

时间:2017-06-04 05:15:06

标签: ruby-on-rails ruby activerecord ruby-on-rails-5

我有经典的has_many: through关系:

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

为了销毁UserGroup记录,我需要销毁UserGroupsUser中的适当记录,这两个记录都是宝石的一部分。否则我会收到错误,即有用户绑定到UserGroups,我无法销毁特定​​的UserGroup

在我的控制器中,我有这个:

  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

然而,当我单击View中的Delete按钮时,它会在我在模态窗口中接受之前销毁一条记录。 如何让destroy行动,在接受视图后,请?我认为不会要求在接受之后,它会冻结through模型中的记录,然后UserGroup

我的&#34;删除&#34;视图中的操作非常规则:

<%= link_to 'Delete', user_group, method: :delete, remote: true, 
data: { confirm: "Do you confirm deleting #{user_group.name}?" }, class: 'btn-danger btn btn-xs' %>

2 个答案:

答案 0 :(得分:0)

只需将has_many :user_groups_users更改为has_many :user_groups_users, :dependent => :destroy

即可

请参阅Association Basics

编辑:你说这是宝石。不是问题,仍然!找到这个类,并在初始化器中添加它(我知道,我知道,有更好的地方,但为了继续这个):

Whatever::To::UserGroupThing.class_eval do 
  has_many :user_group_users, :dependent => :destroy 
end 

但是,如果维护人员对该协会做出某种改变,那么维护可能不是你的朋友。

您还可以在user_group.rb中使用before_destroy挂钩

before_destroy do 
  UserGroupUser.where(:user_group => self).destroy_all
end

答案 1 :(得分:0)

为了简化整个过程,您只需向before_destroy添加UserGroup回调即可。它只会在您运行@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

阅读ActiveRecord Callbacks