ruby 如何销毁一个has_many users没有通过验证/回调的父对象(company)

busg9geu  于 2023-06-22  发布在  Ruby
关注(0)|答案(2)|浏览(139)

我有一个Company模型has_many :users, dependent: :destroyUser模型有一个before_destroy :validate_remaining_admins回调方法,可以防止破坏公司的最后一个管理员用户。

def validate_remaining_admins
  return unless admin?

  remaining_admins = company.users.where.not(id: id).admin
  if company && !company.marked_for_destruction? && remaining_admins.empty?
    errors.add(:base, :validate_remaining_admins)
    throw(:abort)
  end
end

到目前为止一切都很好,但我正在努力摧毁公司。解决这种问题的最佳实践是什么?
我尝试从关联中删除dependent: :destroy,并创建一个before_destroy方法,该方法对关联用户执行delete_all操作。但是,如果出现问题,所有用户都会消失,那么就会出现回滚问题。after_destroy有一个外键问题。
在destroy之前传递一个属性来删除用户似乎也很笨拙。
最后,它应该摧毁公司及其所有使用@company.destroy的用户。

8ftvxx2r

8ftvxx2r1#

class Company < ApplicationRecord

has_many :users, dependent: :destroy



before_destroy :destroy_users


private


def destroy_users
users.destroy_all

  end

end

我们可以尝试,删除依赖项::destroy选项从公司和用户模型之间的关联。
相反,在Company模型中定义一个before_destroy回调,名为destroy_users。在此方法中,使用destroy_all方法删除公司的所有关联用户。
通过这样做,当您调用@company.destroy时,它将触发destroy_users方法,该方法将在公司本身被销毁之前删除所有关联的用户。
关于你提到的回滚问题,destroy_all方法就是用来处理这种情况的。如果在删除用户的过程中发生错误,则事务将回滚,并且公司不会被破坏。
希望这个解决方案提供了一种安全、干净的方法,可以使用@ company. destroy销毁一个公司及其所有关联用户。

x6yk4ghg

x6yk4ghg2#

通过覆盖company模型的destroy方法来修复它:

def destroy
  mark_for_destruction
  super
end

def destroy!
  mark_for_destruction
  super
end

autosave: true不一定要在使用此方法的用户的has_many关联中。

相关问题