【问题标题】:Rails 5.1.: destroy records in "has_many: through" association with restrictionRails 5.1.:销毁“has_many:通过”关联中的记录与限制
【发布时间】:2017-11-05 04:00:31
【问题描述】:

我有经典的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 中的相应记录,这两者都是 gem 的一部分。否则我将返回错误,即有用户绑定到用户组,我无法销毁特定​​的 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

但是,当我在视图中单击删除按钮时,它会在我在模态窗口中接受之前破坏记录。 我如何使它在destroy 行动中,请在接受后? .

我在 View 中的“删除”操作很正常:

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

【问题讨论】:

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


    【解决方案1】:

    只需将has_many :user_groups_users 更改为has_many :user_groups_users, :dependent =&gt; :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
    

    【讨论】:

    • 我知道这一点,但是我不能这样做,因为 UserGroupsUser 模型在 gem 中。有没有其他方法可以做到这一点?
    • 谢谢。第二个解决方案会进入我的控制器,对吗?第一个非常棘手,因为正如您所说 - gem 的维护者可能会更改模型中的某些内容。
    • 被扔进你的 user_group.rb 模型中。
    • 谢谢,也许这会起作用,但是除了User 模型我不能修改任何东西。我想我会从不同的角度来做。我将允许current_user 解开特定用户组中的所有用户,然后如果特定组中没有用户,我将自动删除该组。我什至可以向current_user 发出警告,它是该组的最后一个用户,如果组中没有用户,它将被删除。我不想在我的数据库中保留任何未使用的项目。此外,这将继续防止某些用户似乎失去任何组并且基本上无能为力的情况。
    【解决方案2】:

    为了简化整个事情,您只需将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

    【讨论】:

    • 由于模型在 gem 中,我无法修改它。我所有的自定义修改都必须在我的控制器中完成。请问我可以在那里做类似的事情吗?
    • @matiss 哪个宝石?
    • 我在Strongbolt 实现了允许为current_user 创建自定义用户组的功能。
    • 目前模型中基本上有这个:dependent =&gt; :restrict_with_exception,我无法修改它。
    猜你喜欢
    • 2015-06-01
    • 1970-01-01
    • 2017-11-27
    • 1970-01-01
    • 2019-09-23
    • 2015-03-16
    • 2012-01-01
    • 1970-01-01
    • 2011-12-04
    相关资源
    最近更新 更多