Load data from id for a policy check during a create action

I have a create action that will create a new Offer, that offer needs to be related to a Property, so one of the fields I accept as input is a property_id. In my policies, I need to check some of this property fields, meaning that I need to load that property and make it accessible to that action policies somehow. How can I do such a thing with Ash? Also, can I make the whole process inside a transaction? Meaning that I have strong guarantees that what I'm checking in the policy is actually what is in the database at that time (avoiding race conditions).
3 Replies
ZachDaniel
ZachDaniel3y ago
All creates and updates are in transactions by default. Look into custom simple checks, and make queries in that check module to inspect the property.
Blibs
BlibsOP3y ago
Ah, that makes sense! This is what I came up with:
defmodule Marketplace.Markets.Property.Offer.Checks.IsPropertyOpen do
use Ash.Policy.SimpleCheck

def describe(_), do: "property has open status"

def match?(actor, %{changeset: %{attributes: %{property_id: property_id}}}, _) do
case Marketplace.Markets.Property.get(%{id: property_id}, actor: actor) do
{:ok, %{status: :open}} -> true
_ -> false
end
end
end
defmodule Marketplace.Markets.Property.Offer.Checks.IsPropertyOpen do
use Ash.Policy.SimpleCheck

def describe(_), do: "property has open status"

def match?(actor, %{changeset: %{attributes: %{property_id: property_id}}}, _) do
case Marketplace.Markets.Property.get(%{id: property_id}, actor: actor) do
{:ok, %{status: :open}} -> true
_ -> false
end
end
end
A question about this, let's say I want to do another policy that also needs to check something related to the property and I want to be a separated policy.. In that case I would need to query the database twice to fetch the property or can I somehow pass the property to the other custom policy somehow?
ZachDaniel
ZachDaniel3y ago
Right now there is not a way to cache that information. What you’d do is make a change that runs on those actions and sets the data into the changeset context And then the policies could read from the changeset context

Did you find this page helpful?