{@thread.name}

Eduardo B. Alexandre
2023-06-03

Eduardo B. Alexandre:

Let’s say I have a Post resource, and I want to create a read action that instead of returning a specific Post , I want it just to check if the post exists and return only true/false just like Ecto’s Repo.exists? does.

Is that possible with Ash?

zachdaniel:

Currently we do not have that, but it will be added at some point. You can write a generic action in the meantime to simulate it

zachdaniel:

Or you could use Ash.Query.datalayer_query and pass that to ecto.

Eduardo B. Alexandre:

Here is my solution:

actions do
  require Ash.Query

  action :exists, :boolean do
    argument :id, :uuid, allow_nil?: false

    run(fn input, context ->
      id = input.arguments.id
      repo = AshPostgres.DataLayer.Info.repo(__MODULE__)

      {:ok, ecto_query} =
        __MODULE__ |> Ash.Query.filter(id == ^id) |> Ash.Query.data_layer_query()

      {:ok, repo.exists?(ecto_query)}
    end)
  end
end

Are you aware of some way to to the same without having to use data_layer_query ? I tried simulating the exists? feature with Ash.Query.select(1) |> Ash.Query.limit(1) but using 1 for the select function call is not supported.

zachdaniel:

doing select(:id) would be roughly equivalent

zachdaniel:

but currently its either selecting a field or using the repo like you did

rgraff:

<@197905764424089601> does this solution respect multitenancy and policies? Not sure if those are apply at the query or action level

zachdaniel:

It does not. Those happen at the action level. Actually I’d have to double check on multitenancy

zachdaniel:

But that’s the reason I’d suggest opting for the select id approach.