jclement

jclement

Guidance on using Ash and Flop together?

Hi there,

As the title suggests, I’m trying to use Ash and Flop together for some lovely table-magic. Hopefully this is a reasonable question to ask in this topic.

My resource is set up with:

  • Attribute based multi-tenancy
  • Policies to enforce read-permissions

I’d like to use Flop / Flop Phoenix to give the user an interactive grid they can use to sift through the dataset, but I want to ensure that:
a) Data isn’t exposed across tenants
b) Users can only see records that they are allowed to see (based on the Ash Policy)
c) In the future I can make use of Ash calculated fields, etc.

What I’d like to be able to say is something like the following, but that’s obviously mixing Ash.Query and Ecto.Query types.

Customers.Customer
|> Ash.Query.for_read(:read, %{}, actor: socket.assigns.current_user)
|> Ash.Query.set_tenant(socket.assigns.current_tenant)
|> Flop.validate_and_run(params, for: Customers.Customer)

The best I’ve been able to do is the following, but I don’t like that I could easily miss the multi-tenancy filter, and my read-level policies aren’t being followed:

{:ok, query} = Customers.Customer
# specifying actor and authorize?=true doesn't do anything here
|> Ash.Query.for_read(:read)
# have to manually add tenant filter here.  set_tenant has no effect.
|> Ash.Query.filter(tenant_id == ^socket.assigns.current_tenant.id)
# Get an Ecto.Query which includes at least some of my filters
|> Ash.Query.data_layer_query()

customers = Flop.validate_and_run(query, params, for: Customers.Customer)

I assume I’m missing something obvious here and would appreciate a nudge in the right direction.

Thank you so much!

Marked As Solved

frankdugan3

frankdugan3

It’s also worth pointing out that a lot of what Flop offers is already handled in Ash. Ash supports filtering, sorting and pagination out of the box, and AshPhoenix has some tooling for parsing filters/sorts/pagination from params.

Also Liked

zachdaniel

zachdaniel

Creator of Ash

Unfortunately I don’t think that flop and Ash will ever play fully nicely together. They are at different levels of abstraction.

To answer your question, though, you will want to look at Ash.can and the accompanying options to take a query and apply policy filters for a given action.

With that said, not all policies or action invariants can be simulated this way. Some policies(if you currently have any of these then you probably already know) can only be enforced after running the query. Some actions have after action hooks that expect to be able to modify the return, not all calculated fields can be lowered to the query, etc.

You may be able to get what you want with flop in the short term but in the long term we will need our own equivalent tooling.

Flop and Ecto exist at a “data” level of abstraction whereas Ash models “domain actions”, only one component of which is the data that powers them.

Where Next?

Popular in Questions Top

chokchit
** (DBConnection.ConnectionError) connection not available and request was dropped from queue after 2733ms. You can configure how long re...
New
Kurisu
For example for a current url like http://localhost:4000/cosmetic/products?_utf8=✓&query=perfume&page=2, I would like to get: ...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
lucidguppy
I have a super simple question about elixir - how would I take a file like this foo bar baz and output a new file that enumerates th...
New
srinivasu
How to handle excepions in elixir? Suppose i have A, B, C ,D, E modules. and each module has get() function. A.get() method will call t...
New
komlanvi
Hi everyone, I was playing with phoenix liveView but I run into an issue. I have a form and want to validate each input text when the te...
New
hariharasudhan94
I would like to know what is the best IDE for elixir development?
New
jaysoifer
Is there a way to rollback a specific migration and only that one (“skipping” all the other ones)? Would mix ecto.rollback -v 200809061...
New
vegabook
I’m brand new to Phoenix and I have stripped one of the demo applications to the bone. I just want to get an svg up on the screen. Here i...
New
dokuzbir
I want to highlight html closing tags when i click a html tag. That works in .html files but doesnt work for html.eex templates. How can...
New

Other popular topics Top

New
hariharasudhan94
lets say i have a sample like a = 20; b = 10; if (a > b) do {:ok, "a"} end if (a < b) do {:ok, b} end if (a == b) do {:ok, "equa...
New
mcarvalho
What is the difference between System.get_env and Application.get_env? For example, what are best practices to use one versus another.
New
Patoshizzle
After calling mix ecto.create I get this error: 17:00:32.162 [error] GenServer #PID<0.412.0> terminating ** (Postgrex.Error) FATAL...
New
minhajuddin
I have seen a lot of code which picks the first element from a list using Enum.at(0) instead of List.first. Is there a reason why people ...
New
aesmail
Hello guys, I have finally made it. I created an admin interface for a framework. It’s been on my todo list for years and with the curre...
New
fayddelight
I tried installing elixir 1.11.2 erlang 23.3.4 via asdf in my zsh shell. Enabled the versions locally and globally. When I list them ...
New
bsollish-terakeet
Credo is smart enough to check for (something like) this: assert length(the_list) == 0 with this response: Checking if an enum is empt...
New
saif
Hello everyone, Long time lurker first time poster here. I’ve recently begun working on Elixir full-time again! :raised_hands: It’s been...
New
jononomo
For some reason my phoenix channels are working for me in my local dev environment, but as soon as I deploy via Docker, I get a 403 error...
New

We're in Beta

About us Mission Statement