Can't add form with auto forms

I'm getting this error when setting up with auto forms. Attempted to add a form at path: [:budget_allocations], but no create_action was configured. here is my action
update :user_update do
argument :budget_allocations, {:array, :map}
change manage_relationship(:budget_allocations, type: :append_and_remove)
end
update :user_update do
argument :budget_allocations, {:array, :map}
change manage_relationship(:budget_allocations, type: :append_and_remove)
end
and the form
form =
transaction
|> AshPhoenix.Form.for_update(:user_update,
api: QueryDesk.Api,
forms: [auto?: true]
)
|> to_form()
|> AshPhoenix.Form.add_form([:budget_allocations])
form =
transaction
|> AshPhoenix.Form.for_update(:user_update,
api: QueryDesk.Api,
forms: [auto?: true]
)
|> to_form()
|> AshPhoenix.Form.add_form([:budget_allocations])
58 Replies
ZachDaniel
ZachDanielβ€’2y ago
Add the type: :read option to your add form call Because you’re technically looking up one to relate
michaelst
michaelstOPβ€’2y ago
so that works when I add the form when initially creating it, buth handling it on an event is giving a strange error
def handle_event("split", _params, socket) do
form = AshPhoenix.Form.add_form(socket.assigns.form, [:budget_allocations], type: :read)
{:noreply, assign(socket, form: form)}
end
def handle_event("split", _params, socket) do
form = AshPhoenix.Form.add_form(socket.assigns.form, [:budget_allocations], type: :read)
{:noreply, assign(socket, form: form)}
end
warning: the following fields are unknown when raising Ash.Error.Query.NoSuchFunction: [resource: Spendable.Transaction]
ZachDaniel
ZachDanielβ€’2y ago
πŸ€” that is very strange thats just the warning though, not the actual error what does the error itself look like?
michaelst
michaelstOPβ€’2y ago
oh I think I see something else in there about actor not existing as a function... let me dig into that so it looks like user is no longer set as actor in handle_event I have a change that is accessing the actor
warning: the following fields are unknown when raising Ash.Error.Query.NoSuchFunction: [resource: Spendable.Transaction]. Please make sure to only give known fields when raising or redefine Ash.Error.Query.NoSuchFunction.exception/1 to discard unknown fields. Future Elixir versions will raise on unknown fields given to raise/2
(ash 2.10.2) lib/ash/error/query/no_such_function.ex:5: Ash.Error.Query.NoSuchFunction."exception (overridable 1)"/1
(ash 2.10.2) lib/ash/filter/filter.ex:2802: Ash.Filter.resolve_call/2
(ash 2.10.2) lib/ash/filter/filter.ex:3062: anonymous fn/3 in Ash.Filter.do_hydrate_refs/2
(elixir 1.15.1) lib/enum.ex:4830: Enumerable.List.reduce/3
(elixir 1.15.1) lib/enum.ex:2564: Enum.reduce_while/3
(ash 2.10.2) lib/ash/filter/filter.ex:3061: Ash.Filter.do_hydrate_refs/2
(ash 2.10.2) lib/ash/filter/filter.ex:2674: Ash.Filter.resolve_call/2
(ash 2.10.2) lib/ash/filter/filter.ex:2138: Ash.Filter.add_expression_part/3
(ash 2.10.2) lib/ash/filter/filter.ex:2076: anonymous fn/3 in Ash.Filter.parse_expression/2
(elixir 1.15.1) lib/enum.ex:4830: Enumerable.List.reduce/3
(elixir 1.15.1) lib/enum.ex:2564: Enum.reduce_while/3
(ash 2.10.2) lib/ash/filter/filter.ex:312: Ash.Filter.parse/5
(ash 2.10.2) lib/ash/query/query.ex:2152: Ash.Query.do_filter/2
(ash 2.10.2) lib/ash/engine/request.ex:871: Ash.Engine.Request.do_runtime_filter/4
(ash 2.10.2) lib/ash/engine/request.ex:670: Ash.Engine.Request.apply_filter/4
(ash 2.10.2) lib/ash/engine/request.ex:561: Ash.Engine.Request.do_strict_check/3
(ash 2.10.2) lib/ash/engine/request.ex:522: anonymous fn/2 in Ash.Engine.Request.strict_check/2
(elixir 1.15.1) lib/enum.ex:4830: Enumerable.List.reduce/3

[warning] Unhandled error in form submission for Spendable.Transaction.user_update

This error was unhandled because it did not implement the `AshPhoenix.FormData.Error` protocol.

** (Ash.Error.Query.NoSuchFunction) No such function actor
warning: the following fields are unknown when raising Ash.Error.Query.NoSuchFunction: [resource: Spendable.Transaction]. Please make sure to only give known fields when raising or redefine Ash.Error.Query.NoSuchFunction.exception/1 to discard unknown fields. Future Elixir versions will raise on unknown fields given to raise/2
(ash 2.10.2) lib/ash/error/query/no_such_function.ex:5: Ash.Error.Query.NoSuchFunction."exception (overridable 1)"/1
(ash 2.10.2) lib/ash/filter/filter.ex:2802: Ash.Filter.resolve_call/2
(ash 2.10.2) lib/ash/filter/filter.ex:3062: anonymous fn/3 in Ash.Filter.do_hydrate_refs/2
(elixir 1.15.1) lib/enum.ex:4830: Enumerable.List.reduce/3
(elixir 1.15.1) lib/enum.ex:2564: Enum.reduce_while/3
(ash 2.10.2) lib/ash/filter/filter.ex:3061: Ash.Filter.do_hydrate_refs/2
(ash 2.10.2) lib/ash/filter/filter.ex:2674: Ash.Filter.resolve_call/2
(ash 2.10.2) lib/ash/filter/filter.ex:2138: Ash.Filter.add_expression_part/3
(ash 2.10.2) lib/ash/filter/filter.ex:2076: anonymous fn/3 in Ash.Filter.parse_expression/2
(elixir 1.15.1) lib/enum.ex:4830: Enumerable.List.reduce/3
(elixir 1.15.1) lib/enum.ex:2564: Enum.reduce_while/3
(ash 2.10.2) lib/ash/filter/filter.ex:312: Ash.Filter.parse/5
(ash 2.10.2) lib/ash/query/query.ex:2152: Ash.Query.do_filter/2
(ash 2.10.2) lib/ash/engine/request.ex:871: Ash.Engine.Request.do_runtime_filter/4
(ash 2.10.2) lib/ash/engine/request.ex:670: Ash.Engine.Request.apply_filter/4
(ash 2.10.2) lib/ash/engine/request.ex:561: Ash.Engine.Request.do_strict_check/3
(ash 2.10.2) lib/ash/engine/request.ex:522: anonymous fn/2 in Ash.Engine.Request.strict_check/2
(elixir 1.15.1) lib/enum.ex:4830: Enumerable.List.reduce/3

[warning] Unhandled error in form submission for Spendable.Transaction.user_update

This error was unhandled because it did not implement the `AshPhoenix.FormData.Error` protocol.

** (Ash.Error.Query.NoSuchFunction) No such function actor
ZachDaniel
ZachDanielβ€’2y ago
πŸ€” what on earth
michaelst
michaelstOPβ€’2y ago
iex(12)> warning: the following fields are unknown when raising Ash.Error.Query.NoSuchFunction: [resource: Spendable.Transaction]. Please make sure to only give known fields when raising or redefine Ash.Error.Query.NoSuchFunction.exception/1 to discard unknown fields. Future Elixir versions will raise on unknown fields given to raise/2
(ash 2.10.2) lib/ash/error/query/no_such_function.ex:5: Ash.Error.Query.NoSuchFunction."exception (overridable 1)"/1
(ash 2.10.2) lib/ash/filter/filter.ex:2802: Ash.Filter.resolve_call/2
(ash 2.10.2) lib/ash/filter/filter.ex:3062: anonymous fn/3 in Ash.Filter.do_hydrate_refs/2
(elixir 1.15.1) lib/enum.ex:4830: Enumerable.List.reduce/3
(elixir 1.15.1) lib/enum.ex:2564: Enum.reduce_while/3
(ash 2.10.2) lib/ash/filter/filter.ex:3061: Ash.Filter.do_hydrate_refs/2
(ash 2.10.2) lib/ash/filter/filter.ex:2674: Ash.Filter.resolve_call/2
(ash 2.10.2) lib/ash/policy/check/expression.ex:3: Ash.Policy.Check.Expression.try_eval/2
(ash 2.10.2) lib/ash/policy/check/expression.ex:3: Ash.Policy.Check.Expression.try_strict_check/3
(ash 2.10.2) lib/ash/policy/policy.ex:164: Ash.Policy.Policy.fetch_or_strict_check_fact/2
(ash 2.10.2) lib/ash/policy/policy.ex:479: Ash.Policy.Policy.compile_policy_expression/2
(ash 2.10.2) lib/ash/policy/policy.ex:68: Ash.Policy.Policy.build_requirements_expression/2
(ash 2.10.2) lib/ash/policy/policy.ex:26: Ash.Policy.Policy.solve/1
(ash 2.10.2) lib/ash/policy/checker.ex:82: Ash.Policy.Checker.strict_check_scenarios/1
(ash 2.10.2) lib/ash/policy/authorizer.ex:772: Ash.Policy.Authorizer.strict_check_result/1
(ash 2.10.2) lib/ash/policy/authorizer.ex:376: Ash.Policy.Authorizer.strict_check/2
(ash 2.10.2) lib/ash/engine/request.ex:554: Ash.Engine.Request.do_strict_check/3
(ash 2.10.2) lib/ash/engine/request.ex:522: anonymous fn/2 in Ash.Engine.Request.strict_check/2
iex(12)> warning: the following fields are unknown when raising Ash.Error.Query.NoSuchFunction: [resource: Spendable.Transaction]. Please make sure to only give known fields when raising or redefine Ash.Error.Query.NoSuchFunction.exception/1 to discard unknown fields. Future Elixir versions will raise on unknown fields given to raise/2
(ash 2.10.2) lib/ash/error/query/no_such_function.ex:5: Ash.Error.Query.NoSuchFunction."exception (overridable 1)"/1
(ash 2.10.2) lib/ash/filter/filter.ex:2802: Ash.Filter.resolve_call/2
(ash 2.10.2) lib/ash/filter/filter.ex:3062: anonymous fn/3 in Ash.Filter.do_hydrate_refs/2
(elixir 1.15.1) lib/enum.ex:4830: Enumerable.List.reduce/3
(elixir 1.15.1) lib/enum.ex:2564: Enum.reduce_while/3
(ash 2.10.2) lib/ash/filter/filter.ex:3061: Ash.Filter.do_hydrate_refs/2
(ash 2.10.2) lib/ash/filter/filter.ex:2674: Ash.Filter.resolve_call/2
(ash 2.10.2) lib/ash/policy/check/expression.ex:3: Ash.Policy.Check.Expression.try_eval/2
(ash 2.10.2) lib/ash/policy/check/expression.ex:3: Ash.Policy.Check.Expression.try_strict_check/3
(ash 2.10.2) lib/ash/policy/policy.ex:164: Ash.Policy.Policy.fetch_or_strict_check_fact/2
(ash 2.10.2) lib/ash/policy/policy.ex:479: Ash.Policy.Policy.compile_policy_expression/2
(ash 2.10.2) lib/ash/policy/policy.ex:68: Ash.Policy.Policy.build_requirements_expression/2
(ash 2.10.2) lib/ash/policy/policy.ex:26: Ash.Policy.Policy.solve/1
(ash 2.10.2) lib/ash/policy/checker.ex:82: Ash.Policy.Checker.strict_check_scenarios/1
(ash 2.10.2) lib/ash/policy/authorizer.ex:772: Ash.Policy.Authorizer.strict_check_result/1
(ash 2.10.2) lib/ash/policy/authorizer.ex:376: Ash.Policy.Authorizer.strict_check/2
(ash 2.10.2) lib/ash/engine/request.ex:554: Ash.Engine.Request.do_strict_check/3
(ash 2.10.2) lib/ash/engine/request.ex:522: anonymous fn/2 in Ash.Engine.Request.strict_check/2
ZachDaniel
ZachDanielβ€’2y ago
So that warning looks like some problem with a filter statement being built somewhere
michaelst
michaelstOPβ€’2y ago
oh wait it is set... something else weird is going on
ZachDaniel
ZachDanielβ€’2y ago
Is the primary read action on the destination resource doing some kind of filter?
michaelst
michaelstOPβ€’2y ago
I have something like this on all my resources
policies do
policy always() do
authorize_if action(:create)
authorize_if expr(user_id == actor(:id))
end
end
policies do
policy always() do
authorize_if action(:create)
authorize_if expr(user_id == actor(:id))
end
end
ZachDaniel
ZachDanielβ€’2y ago
policies do
policy always() do
authorize_if action(:create)
authorize_if expr(user_id == ^actor(:id))
end
end
policies do
policy always() do
authorize_if action(:create)
authorize_if expr(user_id == ^actor(:id))
end
end
michaelst
michaelstOPβ€’2y ago
interesting, I haven't touched those, they all worked with graphql, I'm setting up a liveview app now
ZachDaniel
ZachDanielβ€’2y ago
πŸ€” that is surprising That warning is from it constructing an invalid filter error have you confirmed that the policies properly forbid incorrect users?
michaelst
michaelstOPβ€’2y ago
yes, I had tests explicity for that
ZachDaniel
ZachDanielβ€’2y ago
hm...
michaelst
michaelstOPβ€’2y ago
ok the error is gone now, but no form is adding 😞
ZachDaniel
ZachDanielβ€’2y ago
but add_form is returning successfully?
michaelst
michaelstOPβ€’2y ago
it doesn't throw an error and just returns a form
ZachDaniel
ZachDanielβ€’2y ago
πŸ€” can you check the count of form.forms[:budget_allocations]? before and after you add the form
michaelst
michaelstOPβ€’2y ago
forms under form doesn't exist, I do see a forms key, trying to figure out what it is under form.source.forms[:budget_allocations] does have the extra now...
ZachDaniel
ZachDanielβ€’2y ago
hm... could something be wrong with the way you're rendering the forms?
michaelst
michaelstOPβ€’2y ago
I don't think so, the one I add on form creation is showing up
ZachDaniel
ZachDanielβ€’2y ago
if you add two on form creation do they both show up? can you show me your template code?
michaelst
michaelstOPβ€’2y ago
there is an existing one that shows up, I add one through add_forms, but when I do the action it doesn't show up
ZachDaniel
ZachDanielβ€’2y ago
oh, okay so its showing up in the UI but not when you submit?
michaelst
michaelstOPβ€’2y ago
<.inputs_for :let={allocation_form} field={@form[:budget_allocations]}>
<.input
type="select"
field={allocation_form[:budget_id]}
options={Transaction.budget_form_options(@current_user.id)}
/>
<.input type="text" field={allocation_form[:amount]} />
</.inputs_for>
<.inputs_for :let={allocation_form} field={@form[:budget_allocations]}>
<.input
type="select"
field={allocation_form[:budget_id]}
options={Transaction.budget_form_options(@current_user.id)}
/>
<.input type="text" field={allocation_form[:amount]} />
</.inputs_for>
its not showing up in the UI
ZachDaniel
ZachDanielβ€’2y ago
are you reassigning the form and all that?
michaelst
michaelstOPβ€’2y ago
def handle_event("split", _params, socket) do
IO.inspect length(socket.assigns.form.source.params["budget_allocations"])
form = AshPhoenix.Form.add_form(socket.assigns.form, [:budget_allocations], type: :read)
IO.inspect length(form.source.params["budget_allocations"])
{:noreply, assign(socket, form: form)}
end
def handle_event("split", _params, socket) do
IO.inspect length(socket.assigns.form.source.params["budget_allocations"])
form = AshPhoenix.Form.add_form(socket.assigns.form, [:budget_allocations], type: :read)
IO.inspect length(form.source.params["budget_allocations"])
{:noreply, assign(socket, form: form)}
end
ZachDaniel
ZachDanielβ€’2y ago
hmmmmm It not showing up sounds very strange I don't really see how that would happen 😦
michaelst
michaelstOPβ€’2y ago
ya this might be past Ash now, the form definitely has 3 now
ZachDaniel
ZachDanielβ€’2y ago
inputs_for should essentially just loop over each form
michaelst
michaelstOPβ€’2y ago
oh the split button is sending a submit event...
ZachDaniel
ZachDanielβ€’2y ago
ah, yeah you might need type="submit" sorry type="button"
michaelst
michaelstOPβ€’2y ago
well it didn't submit this time.. but still no new form 😭
ZachDaniel
ZachDanielβ€’2y ago
...wacky πŸ€” After you add_form you can inspect form[:budget_allocations]
michaelst
michaelstOPβ€’2y ago
is it maybe a problem with read and trying to create a new one?
ZachDaniel
ZachDanielβ€’2y ago
I don't think so? its possible
michaelst
michaelstOPβ€’2y ago
michaelst
michaelstOPβ€’2y ago
so the first two in that are showing up, the form and second is added during handle_params, the third is added in handle_event if I keep pushing split, those forms are continuing to be added to the assigns form, but the UI isn't updating
ZachDaniel
ZachDanielβ€’2y ago
πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” πŸ€” did you confirm that adding additional forms on the initial form works?
michaelst
michaelstOPβ€’2y ago
ya I still have that piece in
ZachDaniel
ZachDanielβ€’2y ago
thats so weird
michaelst
michaelstOPβ€’2y ago
GitHub
spendable/spendable/lib/spendable_web/live/transactions.ex at 2c730...
Budgeting app built on Phoenix and React. Contribute to michaelst/spendable development by creating an account on GitHub.
ZachDaniel
ZachDanielβ€’2y ago
like the same code on the mount vs the same code in the handle event
michaelst
michaelstOPβ€’2y ago
ZachDaniel
ZachDanielβ€’2y ago
uh...okay something is definitely wrong πŸ˜† Something to do w/ the assigned form/validation step I'd assume I've got to hit the sack, but if you find anything else of note let me know
michaelst
michaelstOPβ€’2y ago
ok, thanks for the help
ZachDaniel
ZachDanielβ€’2y ago
I don't think the type: :read should be the problem it feels like an issue w/ assigns/the validate step, not really sure
michaelst
michaelstOPβ€’2y ago
oh let me try going back to not auto forms
ZachDaniel
ZachDanielβ€’2y ago
yeah good idea to try
michaelst
michaelstOPβ€’2y ago
same result, also I diffed the forms of adding in handle_params vs the event and they are exactly the same, there is something wrong at the rendering layer that is not telling it that something changed
ZachDaniel
ZachDanielβ€’2y ago
maybe try upgrading/downgrading phoenix liveview?
michaelst
michaelstOPβ€’2y ago
it was my custom change action πŸ€¦β€β™‚οΈ Ok with that commented out I'm still runing into some weird behavior with my inputs reseting, also my forms share a name between the resources and they appear to be changing each other. I can provide more details tomorrow
ZachDaniel
ZachDanielβ€’2y ago
something is super strange is happening here then maybe missing hidden inputs? but IIRC the inputs_for component renders the hidden fields okay, interesting so the value in the example you sent me seems wrong
@impl true
def input_value(form, _form, field) do
AshPhoenix.Form.value(form, field)
end
@impl true
def input_value(form, _form, field) do
AshPhoenix.Form.value(form, field)
end
I think we might need to do something like this:
@impl true
def input_value(form, phoenix_form, field) do
if form.source.forms[field] do
Phoenix.HTML.FormData.to_form(form, phoenix_form, field, [])
else
AshPhoenix.Form.value(form, field)
end
end
@impl true
def input_value(form, phoenix_form, field) do
if form.source.forms[field] do
Phoenix.HTML.FormData.to_form(form, phoenix_form, field, [])
else
AshPhoenix.Form.value(form, field)
end
end
This may be a bug with the new phoenix pattern of inputs_for .... @form[:relationship]
michaelst
michaelstOPβ€’2y ago
anything I can help to test or implement? any other details you need?
ZachDaniel
ZachDanielβ€’2y ago
If you could clone down ash_phoenix and try out that change to input_value that would be great πŸ™‚ I wont be at my computer much given the holiday
michaelst
michaelstOPβ€’2y ago
yep I can do that, totally understand got this error key :forms not found in: #Ash.Changeset< on this line if form.source.forms[field] do changed it to use phoenix_form with that change it still resets my fields and is changing the parent amount field I checked it does evaluate true and use that path I'm so confused, but somehow it started working, I've been playing with the mange_relationship types, budget_allcations needed to be direct_control and revert back to type: :update I definitely need to write a guide for this with a working configuration
ZachDaniel
ZachDanielβ€’2y ago
Whatttt And yes, I agree, we need better guides on this one.

Did you find this page helpful?