如何防止最后 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
我们有 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