sezaru
I have this attribute in my resource:
attribute :status, :atom do
allow_nil? false
public? true
constraints one_of: [:draft, :open, :pending, :sold, :inactive]
default :draft
end
And I have a read action that I call via AshGraphql to retrieve data from that resource.
When I try to filter that call by the status attribute, I’m getting an error.
Here is my graphql query:
query {
listValidProperties(
filter: {
status: {in: ["OPEN", "PENDING", "SOLD"]}
}
limit: 5
offset: 0
) {
results {
id
}
}
}
I get the following error in the terminal:
[warning] `96e7c8cc-071b-4623-a8a3-cad0b578f02f`: AshGraphql.Error not implemented for error:
** (Ash.Error.Query.InvalidFilterValue) Invalid filter value `status in ["OPEN", "PENDING", "SOLD"]`: No matching types. Possible types: [[:any, {:array, :same}]]
(elixir 1.17.2) lib/process.ex:864: Process.info/2
(ash 3.4.8) lib/ash/error/query/invalid_filter_value.ex:5: Ash.Error.Query.InvalidFilterValue.exception/1
(ash 3.4.8) lib/ash/query/operator/operator.ex:184: Ash.Query.Operator.try_cast_with_ref/3
(ash 3.4.8) lib/ash/filter/filter.ex:4015: anonymous fn/5 in Ash.Filter.parse_predicates/3
(elixir 1.17.2) lib/enum.ex:4858: Enumerable.List.reduce/3
(elixir 1.17.2) lib/enum.ex:2585: Enum.reduce_while/3
(ash 3.4.8) lib/ash/filter/filter.ex:2764: Ash.Filter.add_expression_part/3
(ash 3.4.8) lib/ash/filter/filter.ex:2902: anonymous fn/3 in Ash.Filter.add_expression_part/3
(elixir 1.17.2) lib/enum.ex:4858: Enumerable.List.reduce/3
(elixir 1.17.2) lib/enum.ex:2585: Enum.reduce_while/3
(ash 3.4.8) lib/ash/filter/filter.ex:2901: Ash.Filter.add_expression_part/3
(ash 3.4.8) lib/ash/filter/filter.ex:2460: anonymous fn/3 in Ash.Filter.parse_expression/2
(elixir 1.17.2) lib/enum.ex:4858: Enumerable.List.reduce/3
(elixir 1.17.2) lib/enum.ex:2585: Enum.reduce_while/3
(ash 3.4.8) lib/ash/filter/filter.ex:334: Ash.Filter.parse/3
(ash 3.4.8) lib/ash/query/query.ex:2699: Ash.Query.do_filter/3
(stdlib 6.0.1) maps.erl:860: :maps.fold_1/4
(ash_graphql 1.3.4) lib/graphql/resolver.ex:423: AshGraphql.Graphql.Resolver.resolve/2
(absinthe 1.7.8) lib/absinthe/phase/document/execution/resolution.ex:234: Absinthe.Phase.Document.Execution.Resolution.reduce_resolution/1
(absinthe 1.7.8) lib/absinthe/phase/document/execution/resolution.ex:189: Absinthe.Phase.Document.Execution.Resolution.do_resolve_field/3
(absinthe 1.7.8) lib/absinthe/phase/document/execution/resolution.ex:174: Absinthe.Phase.Document.Execution.Resolution.do_resolve_fields/6
(absinthe 1.7.8) lib/absinthe/phase/document/execution/resolution.ex:145: Absinthe.Phase.Document.Execution.Resolution.resolve_fields/4
(absinthe 1.7.8) lib/absinthe/phase/document/execution/resolution.ex:88: Absinthe.Phase.Document.Execution.Resolution.walk_result/5
(absinthe 1.7.8) lib/absinthe/phase/document/execution/resolution.ex:67: Absinthe.Phase.Document.Execution.Resolution.perform_resolution/3
(absinthe 1.7.8) lib/absinthe/phase/document/execution/resolution.ex:24: Absinthe.Phase.Document.Execution.Resolution.resolve_current/3
(absinthe 1.7.8) lib/absinthe/pipeline.ex:408: Absinthe.Pipeline.run_phase/3
(absinthe_plug 1.5.8) lib/absinthe/plug.ex:536: Absinthe.Plug.run_query/4
(absinthe_plug 1.5.8) lib/absinthe/plug.ex:290: Absinthe.Plug.call/2
(phoenix 1.7.14) lib/phoenix/router/route.ex:42: Phoenix.Router.Route.call/2
(phoenix 1.7.14) lib/phoenix/router.ex:484: Phoenix.Router.__call__/5
(core 1.91.3) lib/core_web/endpoint.ex:1: CoreWeb.Endpoint.plug_builder_call/2
(core 1.91.3) deps/plug/lib/plug/debugger.ex:136: CoreWeb.Endpoint."call (overridable 3)"/2
(core 1.91.3) lib/core_web/endpoint.ex:1: CoreWeb.Endpoint."call (overridable 4)"/2
(core 1.91.3) lib/core_web/endpoint.ex:1: CoreWeb.Endpoint.call/2
(phoenix 1.7.14) lib/phoenix/endpoint/sync_code_reload_plug.ex:22: Phoenix.Endpoint.SyncCodeReloadPlug.do_call/4
(bandit 1.5.7) lib/bandit/pipeline.ex:124: Bandit.Pipeline.call_plug!/2
(bandit 1.5.7) lib/bandit/pipeline.ex:36: Bandit.Pipeline.run/4
(bandit 1.5.7) lib/bandit/http1/handler.ex:12: Bandit.HTTP1.Handler.handle_data/3
(bandit 1.5.7) lib/bandit/delegating_handler.ex:18: Bandit.DelegatingHandler.handle_data/3
(bandit 1.5.7) /var/home/sezdocs/projects/rebuilt/platform/core/deps/thousand_island/lib/thousand_island/handler.ex:411: Bandit.DelegatingHandler.handle_continue/2
(stdlib 6.0.1) gen_server.erl:2163: :gen_server.try_handle_continue/3
(stdlib 6.0.1) gen_server.erl:2072: :gen_server.loop/7
(stdlib 6.0.1) proc_lib.erl:329: :proc_lib.init_p_do_apply/3
And the following error as a response in graphql:
{
"data": {
"listValidProperties": null
},
"errors": [
{
"message": "Something went wrong. Unique error id: `96e7c8cc-071b-4623-a8a3-cad0b578f02f`",
"path": [
"listValidProperties"
],
"locations": [
{
"line": 2,
"column": 2
}
]
}
]
}
This used to work in Ash2 btw
Trending in Questions
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
So my question is quite simple and i have found no conclusive answer on forum, google or AI.
Should we use :erlang.float for Integer to ...
New
Hello,
I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
If a change or preparation module uses Ash.Changeset.get_argument/2 or Ash.Query.get_argument/2 (or any of the other get_argument functio...
New
apply_graft/2 doesn’t rewrite an add_many sub-workflow’s deps on an add step. Grafted jobs cancel with “upstream job was deleted”
Version...
New
Other Trending Topics
I am happy to introduce the very α version of the new programming language compiled to BEAM.
Welcome Cure.
It has literally three kille...
New
Hi there! We created Gust: A task orchestrator inspired by Airflow.
For those who have never heard about Aiflow, it’s a Python-based wor...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New
Hello everyone. After busy few months I am happy to announce v0.1.0 of Emerge & Solve.
They are GUI (Emerge) and State management (S...
New
Corex is an accessible, unstyled UI component library for Phoenix that integrates Zag.js state machines using Vanilla JavaScript and Live...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #elixirconf-us
- #ai
- #blog-post
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #api
- #forms
- #hex
- #security
- #metaprogramming










Showing Posts 17 to 8- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
zachdaniel
The
add_calculationscallback is where we determine the calculations, and then inadd_field_level_authfunction in the read action logic.sezaru
Would you mind giving me some hints which files/functions the field policies code path is run? I can take a look into it when I have some free time in my hands.
zachdaniel
Yeah, I’d imagine this area is rife for optimizations
Ultimately, I think having fewer field policies is better than one policy per field from a conceptual standpoint, and we should come up with a way for you to write either a deny-list or an allow-list.
I’d be willing to bet that we could eliminate most if not all of that additional processing time via optimizing those code paths. If you could open an issue on Ash showing this info that would be great. I won’t have the time to optimize this in the near future, unfortunately, but perhaps an adventurous soul can investigate.
sezaru
I just added some more benchmark numbers:
Legend:
disabled: field_policies are fully disabled
catch_all_always: there is only one field_policy with a catch_all that always authorize
catch_all_roles: there is only one field_policy with a catch_all that checks for the role
always: have a field_policy per attribute that always authorize
bypass_roles: have a field_policy_bypass per attribute that will check for the role
roles: have a field_policy per attribute that will check for the role
It is interesting to see that even having just one field_policy already makes the query 4x slower than not having any check at all
sezaru
So, @zachdaniel , I did some benchmark testing here and I think I got some interesting numbers.
The test consists of a resource that contains around 255 attributes. I used the ETS data-layer and added one record to it.
Then, I run a read action to fetch it applying my field policies and another run not applying it.
The benchmark code is as follows:
For the field policies, I added one per attribute, all of them have the same check, I did two types of checks to see if the check itself would be a bottleneck.
Using a check that search for a atom in the
:rolesfield of an agent (based on the HasRole check from ash rbac):Using a always authorize check:
Here are the results:
Seems like there is a very big overhead of creating field policies per field
sezaru
I’m gonna try using the ets datalayer since I think that one would be more consistent on timing.
zachdaniel
Ah, yeah you’re right
Wasn’t thinking. I don’t think there is a good way to just apply field policies TBH. They are implemented as calculations.
sezaru
Hmm, why would that not go to the database? Shouldn’t it fetch all these fields in the load call? At least that’s what I’m seeing here when I tried it.
Here is my code:
zachdaniel
Sort of. You can fetch a record with
select([])and thenAsh.load(thing, [:your, :big, :list, :of :attributes], actor: actor). That tests a bit more than just field policies, but shouldn’t go to the database or anything.sezaru
@zachdaniel is there some call that I can do to just run the field_policies for a resource action without running the full action (like we can use
Ash.can?for normal policies)?Basically I’m creating some benchmarks to test if there is any impact in performance, but it would be great if I can shrink the scope just to the field policies.