不能 :destroy 如果最后存在

cannot :destroy if last existing

设置

我正在使用 Rails 5.2 和 CanCanCan

rails g scaffold Hotel name
rails g scaffold PriceGroup name hotel:references

hotel.rb

has_many :price_groups, dependent: :destroy
validates :price_groups, :presence => true

ability.rb

if user.admin?
  can :manage, :all
else
  can :read, :all
end

挑战

我想确保 Hotel 总是至少有一个 PriceGroup

我如何配置 cancancan 以允许管理员仅在 self.hotel.price_groups.count > 1 时销毁 PriceGroup

我想使用 CanCanCan 工具尽可能在 WebGUI 上显示删除按钮。

是对的,您不应该将业务逻辑添加到能力中。相反,您可以覆盖 PriceGroup 模型中现有的 destroy 操作。

这使您的逻辑具有通用性(意思是,即使是 CanCan 之外的代码也无法删除最后一个对象)。

一个例子是

class PriceGroup < ApplicationRecord

  def destroyable?
    PriceGroup.where(hotel_id: hotel_id).count > 1
  end

  def destroy
    return super if destroyable?
    raise "You cant delete the last price group of hotel #{hotel_id}"
  end 
end

当然你可以让代码更漂亮,但你明白了:)

更新

根据我上面的例子添加CanCan能力

根据文档here,您可以尝试

can(:delete, PriceGroup) { |price_group| price_group.destroyable? }