如何防止最后 child 被销毁,除非 parent 被销毁

How to prevent last child from being destroyed unless parent is destroyed

我们有 2 个简单模型,其中一个 workspace 有许多 memberships。我们需要防止最后一个 membership 被销毁 除非 它的 workspace 被销毁。

此代码不允许我们在销毁工作区时销毁成员资格 -- 谁能告诉我我做错了什么,或者是否有更好的方法来做到这一点?

class Workspace < ApplicationRecord
  has_many :memberships, dependent: :destroy
end
class Membership < ApplicationRecord 
  belongs_to :workspace, counter_cache: true
  before_destroy :ensure_one_member, unless: -> { workspace.destroyed? }
  
  private
  def ensure_one_member
    raise "Can't delete the last member" if workspace.memberships.count == 1
  end
end
% rails c
Loading development environment (Rails 7.0.2.2)
irb(main):001:0> Workspace.last.destroy
  Workspace Load (0.6ms)  SELECT "workspaces".* FROM "workspaces" ORDER BY "workspaces"."id" DESC LIMIT   [["LIMIT", 1]]
  TRANSACTION (0.2ms)  BEGIN                                  
  Membership Load (0.8ms)  SELECT "memberships".* FROM "memberships" WHERE "memberships"."workspace_id" =   [["workspace_id", 3]]
  Membership Count (0.6ms)  SELECT COUNT(*) FROM "memberships" WHERE "memberships"."workspace_id" =   [["workspace_id", 3]]
  TRANSACTION (0.2ms)  ROLLBACK                               
/Users/vince/code/myapp/app/models/membership.rb:6:in `ensure_one_member': Can't delete the last member (RuntimeError)

据我所知,发生回滚是因为 rails 试图在 Workspace 之前删除 Members 所以即使你试图销毁 [=11] 仍然会触发 ensure_one_member =].这不是完美的,但 destroyed_by_association 检查可能会解决您的问题。可以查看相关讨论here