AE
Ash Elixir•3y ago
Blibs

When to use validations or policies

So, continuing the discussion from #general. Can you elaborate more about when should I use validation and when to use policies? If I got it right, seems like I should use policies for things related to the actor and validations to things related to some resource. Is that correct?
5 Replies
Blibs
BlibsOP•3y ago
Another question related to this. I was playing around with validations here, I created this validation:
defmodule Marketplace.Markets.Property.Offer.Checks.IsAValidOffer2 do
alias Ash.Error.Changes.InvalidAttribute

use Ash.Resource.Validation

@impl true
def init(opts), do: {:ok, opts}

@impl true
def validate(changeset, opts) do
%{data: %{status: status}} = changeset

if status == :open do
:ok
else
error = InvalidAttribute.exception(message: "Offer must have a `open` status")

{:error, error}
end
end
end
defmodule Marketplace.Markets.Property.Offer.Checks.IsAValidOffer2 do
alias Ash.Error.Changes.InvalidAttribute

use Ash.Resource.Validation

@impl true
def init(opts), do: {:ok, opts}

@impl true
def validate(changeset, opts) do
%{data: %{status: status}} = changeset

if status == :open do
:ok
else
error = InvalidAttribute.exception(message: "Offer must have a `open` status")

{:error, error}
end
end
end
But the only way I found to apply it was to add it to the validations block in my resources like this:
validations do
validate Checks.IsAValidOffer2,
where: [action_is(:withdraw_offer)]
end
validations do
validate Checks.IsAValidOffer2,
where: [action_is(:withdraw_offer)]
end
This is fine, but I would prefer to add it directly inside my action, is that possible?
ZachDaniel
ZachDaniel•3y ago
Yep! You can just do
validate IsAValidOffer
validate IsAValidOffer
inside the action
Blibs
BlibsOP•3y ago
I tried that, but for some reason it doesn't work, it will not run the validation 🤔 This is how my action is right now:
update :withdraw_offer do
accept [:id]

change set_attribute(:status, :withdrawn)

validate Marketplace.Markets.Property.Offer.Checks.IsAValidOffer2
end
update :withdraw_offer do
accept [:id]

change set_attribute(:status, :withdrawn)

validate Marketplace.Markets.Property.Offer.Checks.IsAValidOffer2
end
Ah... no, ignore it, I found the issue @Zach Daniel is it correct to assume that validations will always run before the policies for a specific action?
ZachDaniel
ZachDaniel•3y ago
Yes
Blibs
BlibsOP•3y ago
All right, thanks!

Did you find this page helpful?