Why don't read actions filter by attributes?

Given a read action
code_interface do
define :read
end

actions do
defaults [:read]
end
code_interface do
define :read
end

actions do
defaults [:read]
end
There are no arguments for the action, so the following does not select on email.
iex(21)> Membership.read(%{email: "[email protected]"}, authorize?: false)
[debug] QUERY OK source="memberships" db=0.6ms queue=0.1ms idle=1341.0ms
SELECT m0."id", m0."role", m0."email", m0."invitation_token", m0."invited_at", m0."inserted_at", m0."updated_at", m0."organization_id", m0."user_id" FROM "memberships" AS m0 []
iex(21)> Membership.read(%{email: "[email protected]"}, authorize?: false)
[debug] QUERY OK source="memberships" db=0.6ms queue=0.1ms idle=1341.0ms
SELECT m0."id", m0."role", m0."email", m0."invitation_token", m0."invited_at", m0."inserted_at", m0."updated_at", m0."organization_id", m0."user_id" FROM "memberships" AS m0 []
I would assume any filterable attributes would be automatically applied as a filter. You could also have an accepts option on the action to limit it certain filterable attributes.
6 Replies
barnabasj
barnabasj2y ago
https://ash-hq.org/docs/guides/ash/latest/code-interface#using-the-code-interface you can use a query for filtering e.g. Membership.read(authorize?: false, query: MemberShip |> Ash.Query.new() |> Ash.Query.filter(email: "[email protected]"))
Ash HQ
Guide: Code Interface
Read the "Code Interface" guide on Ash HQ
ZachDaniel
ZachDaniel2y ago
Yep! And if you want to parse a filter from input (like query params), you'd use Ash.Filter.parse_input! That would prevent any funny business, only allowing basic attribute references to public attributes (and not functions, for example)
Robert Graff
Robert GraffOP2y ago
This is a question more about the philosophy and intent, and less asking "how to?". Yes, we're currently using Ash.Query to filter. My question was "why?" because it seems like such a common use case. I think of using query as an escape hatch of sorts, because I really want my actions to define the intended usecases.
It's similar to how the GraphQL interface creates the input automatically from what's filterable. You don't have to define a read action with arguments for the filterable attributes.
ZachDaniel
ZachDaniel2y ago
Yes, but it does that by using the same feature just laid out, the fact that any given read action can be given a narrowing query And as such ash_graphql supports things like {or: [{...}, {...}]} as opposed to just a key/value of attributes to filter on Its not an escape hatch, its a design benefit of read actions You can support explicit arguments with filters, like:
read :read do
argument :foo, :string
argument :bar, :string
prepare fn query, _ ->
YourHelpers.filter_on_provided_arguments(query, [:foo, :bar])
end
end
read :read do
argument :foo, :string
argument :bar, :string
prepare fn query, _ ->
YourHelpers.filter_on_provided_arguments(query, [:foo, :bar])
end
end
Or you could even write an extension that would add those arguments to all read actions (although I probably wouldn't)
Robert Graff
Robert GraffOP2y ago
I see. It's more about being more robust than a simple key/value filter. Thanks for helping me understand
ZachDaniel
ZachDaniel2y ago
👍 any time!

Did you find this page helpful?