Skip to content
Adam Pahlevi Baihaqi edited this page Sep 26, 2015 · 2 revisions

Rules can be inherited by using inherits options when defining rules for a class.

Bali.map_rules do
  roles_for My::Employee, :roles

  rules_for My::Transaction do
    describe(:supreme_user) { can_all }
    describe :admin_user do
      can_all
      can :cancel,
        if: proc { |record| record.payment_channel == "CREDIT_CARD" &&
                            !record.is_settled? }
    end
    describe :general_user, :finance_user, :monitoring do
      can :ask
    end
    describe "general user", can: [:view, :edit, :update], cannot: [:delete]
    describe "finance user" do
      can :update, :delete, :edit
      can :delete, if: proc { |record| record.is_settled? }
    end # finance_user description
    describe :monitoring do
      cannot_all
      can :monitor
    end
    describe nil do
      can :view
    end
  end # rules_for My::Transaction

  rules_for My::SecuredTransaction, inherits: My::Transaction do
    describe :admin_user do
      can :cancel, if: proc { |record, user|
        record.payment_channel == "CREDIT_CARD" && !record.is_settled &&
          user.exp_years >= 3
      }
    end
    describe :general_user do
      cannot :update, :edit
    end
    describe :finance_user do
      cannot :delete
    end
    describe(nil) { cannot_all }
  end # rules_for My::SecuredTransaction
end

Inheriting rules, as shown above, is done by specifying the inherits options:

rules_for My::SecuredTransaction, inherits: My::Transaction

However, if rules for My::Transaction is not yet defined, a Bali::DslError will be raised. Therefore, any class which rules will be inherited in other class should be defined first.

When inheriting, all rules from its parent class will be inherited, or, become available in it. Shall specific rule is unwanted, one can override it by negating it with cannot, or can, or cannot_all, or can_all as deemed appropriate.

Resetting inherited rules

If an inherited rules is inappropriate only for a limited number of subtarget, we can annul the inherited rules altogether by using clear_rules:

Bali.map_rules do
  rules_for My::SecuredTransaction, inherits: My::Transaction do
    describe :general_user do
      clear_rules
      can :view
    end
  end
end

Without clear_rules, :general_user is supposed to inherit :view, :edit, :update, :ask. But, this way, all those rules are cleared, and now, general_user can only :view.