Best practice to implement dynamic filtering for a read action?
Let's say I have a page that shows a bunch of products for sale.
Now I want to start giving the user options for him to filter some of the products, let's say by department, by mix and/or max price, date, etc.
Not only that but I also want to being able to sort by different fields (ex: price, date).
I was wondering what is the best approach to accomplish that using Ash.
I think I could easily do something like run
for_read
and then do a bunch of Ash.Query.filter
or Ash.Query.sort
depending on what inputs the user sent.
But for me this doesn't seem correct, not only I would be moving business logic to my live module (I'm using LiveView, not GraphQL or JsonAPI in this case) instead of having it all being handled directly in my resources, but I would also be "creating" SQL queries outside my resource, which I don't like because I prefer to limit what the actions other domains can do in my database.
What would you suggest in this case? Is it possible to write an action that would allow me to compose the query depending on its inputs?5 Replies
:wavey: there are a few ways you can approach this
1. add arguments to your action, and switch on them in a preparation
You can add as many arguments and as many prepare statements as you want
Amazing!!
2. filters support passing in simple maps/keyword lists of data. You could build one up based on inputs, and pass it in. You can use
Ash.Query.do_filter/2
which is not a macro in this case (but using Ash.Query.filter/2
is also fine).
3. There is a tool for this in AshPhoenix
called AshPhoenix.FilterForm
It hasn't been documented very well, but it can be used to build filters and then instead of "submitting" the form, you say AshPhoenix.FilterForm.filter(query, form)
)
And if you want it to filter on type you could say something like:
Can
validate
also be invoked inside this? I was looking at validating a field with a regex, but only if the field is present (i.e. not a required field)validations are not supported in read actions currently, but we could add something similar at some point.
But you can do that validation in a custom preparation