如果最后存在,则不能:destroy

时间:2018-08-09 11:31:28

标签: ruby-on-rails cancan cancancan ruby-on-rails-5.2

设置

我正在使用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允许管理员仅在PriceGroup时销毁self.hotel.price_groups.count > 1

我想使用CanCanCan工具在可能的情况下仅在WebGUI上显示删除按钮。

1 个答案:

答案 0 :(得分:4)

什么@meta said是对的,您不应该在此功能中添加业务逻辑。相反,您可以覆盖destroy模型中的现有PriceGroup操作。

这使您的逻辑通用(意味着,即使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? }