Do policies have something like a boolean "not" operator

Hi, I recently wrote this a some policies where I thought having a “not” operator would be useful. For example

policies do
  policy action_type(:create) do
    authorize_if always()
  end

  policy not action_type(:create) do
    authorize_if relates_to_actor_via(:partner)
  end
end

I tried searching the docs, but the best solution I could come up with is

policies do
  policy action_type(:create) do
    authorize_if always()
  end

  bypass action_type(:create) do
    authorize_if always()
  end

  policy always() do
    authorize_if relates_to_actor_via(:partner)
  end
end

Is this a deliberate design choice, or just something that hasn’t been explored yet?

I think nobody has felt enough pain to implement one yet. There is a negate for validations.

https://hexdocs.pm/ash/Ash.Resource.Validation.Builtins.html#negate/1

I think building something similar for policies should be doable.

But Zach will hopefully correct me if I forgot to think about something here :wink:

Mostly, this can be done by switching between authorize_if/forbid_unless and so on. But that doesn’t work for the conditions.

Unfortunately the docs don’t reflect it yet. But action_type also takes a list of action_types so you could do:

policies do
  policy action_type(:create) do
    authorize_if always()
  end

  policy action_type([:read, :update, :destroy]) do
    authorize_if relates_to_actor_via(:partner)
  end
end
1 Like

Yeah, would be great to add a negate check. Checks are more complex than validations, but it could be done. It should be done in core regardless.

1 Like

For my purpose this works perfectly. Thanks for sharing!