Skip to content

Defining rule with if unless condition

Adam Pahlevi Baihaqi edited this page Sep 24, 2015 · 1 revision

Sometimes, a role has a condition. For example, a transaction may only be deleted if the transaction is already settled.

Bali for sure make it easy for you to do this. You can append if or unless proc after the verb, such as:

can :cancel,
  if: proc { |record| record.payment_channel == "CREDIT_CARD" && !record.is_settled? }

This if and unless proc have three variants that can be used to express your rule in sufficient detail:

  1. Zero arity
  2. One arity
  3. Two arity

Given the code example above, it is using the one-arity style. By default, all rules are 0-arity, that is, there is no if and unless proc defined for it.

Let's revise. Say that (for staff) to cancel a transaction, the transaction must not have been settled yet, you need to define the rule by using one-arity rule clause decider:

describe :staff do
  can :cancel, if: { |txn| txn.is_settled? }
  # or, can :cancel, unless: { |txn| txn.is_not_settled? } if is_not_settled? is defined
end

Good, but, in addition to that, how to allow transaction cancellation only to staff who has 3 years or so experience in working with the company?

In order to do that, we need to resort to 2-arity decider, as follow:

describe :staff do
  can :cancel, if: { |txn, usr| txn.is_settled? && usr.exp_years >= 3 }
end