Nested form error - using create when I (think I) want update?
I have a nested form that has been working wonderfully to edit a Site and its related resources, and now I'm attempting to manage the Users who will be permissioned to use the Site as well.
When I click to do my add_form for Users, I get a crash with:
The relationship is many_to_many:
In my action I have:
Because you should only be able to select from the existing users in a select widget and attach them to the Site, not create new users from this form (they require passwords and all that, they have their own separate form for creating). Similar to the tags example I found here, except without creating new ones.
But it looks (based on my current understanding of the error) like the form helper is expecting there to be a create action involved. Am I misunderstanding some component of the system? The form is made like this:
Perhaps
forms: auto?
is getting confused somehow? Have I incompletely specified my resources so as to guide it?48 Replies
Can I see how you are adding the form?
Like your call to
AshPhoenix.Form.add_form
The path used is
"form[edit_users]"
Try this:
form = AshPhoenix.Form.add_form(socket.assigns.form, path, data: the_user_you_want_to_edit, type: :update)
okay so the users are actually getting added from a livecomponent message so that looks like this
adding
type: :update
to that after params changes the error to:
Should this all be pointing at the join resource instead of at the user?oh, so are the users just getting added like "connected" to the form?
You can try
type: :read
The users should be related if they already exist, and I suppose there should be an error of some sort if someone somehow manages to attach a user to the form that doesn't already exist (they're all in a select widget of preexisting users). This form updates Site resources like Domains and Configuration, but the Users section is purely for relating already existing ones.
Then yeah
type: :read
should be what you want πOk, yes, it appears that
type: :read
allows the form to be successfully added to the page, unlike before, nice. I'm not fully understanding why a read type action is used here, is there a section in the guide that might explain that? I know that reads sometimes have to be used in interesting ways until bulk actions are supported, right? Something similar?
Now it's saying
MyApp.Sites.SitesUsers exists, is in the registry, etc, so troubleshooting that now..π€
The reason for using read is because the form itself is not to modify a resource, but to look one up
That error is strange if the resource is definitely in the registry. Could you have passed in the wrong value for api when creating the form?
Sites are in one api, Users are in another. Could that be causing trouble?
Potentially, yeah
In your relationship, if you cross api boundaries, you need to set the
api
option
i.e
In your registry, do you have the resource validations extension?
Yes, both registries have that extension at the top
oh, this is interesting
its likely because of the
through
relationshiphave I munted the relationship :<
Nah, I don't think so
I think this is actually an oversight
try this:
I'm not sure that will work. I think the basic issue is that we're assuming that both the join relationship and the destination are in the same api
yeah that probably won't work. Somewhere where we are managing relationships we are making a bad assumption internally. Need to figure out how to handle this properly. You might be the first person who made a many_to_many across api boundaries
π
okay, so it might work in the interim if you do the example above but explicitly setting the api to the parent api
I'm making a potential fix to ash core that will have the join relationship check either the destination api or the source api for the resource in question
if its not explicitly configured
okay, I'm actually on vacation at the moment so I don't have much time to dedicate to it, but I believe I've just fixed the issue in mind, if you wouldn't mind trying the
main
branch of ash
delete build folder,
mix clean --all
, mix deps.clean --all
, mix deps.get
, mix compile
Same error on form submit
I don't get that error if I do
But the form does not redirect and no data is written. I don't see any errors when IO.inspecting the form at this pointWhen you inspect errors how are you doing it?
try
IO.inspect(AshPhoenix.Form.errors(form, for_path: :all)
%{}
I /believe/ I've got this right according to the ash-hq docs, but neither specifying
:all
nor specifying the specific form path reveals anything:
https://gitlab.com/avoh-labs/panacea/-/blob/main/lib/panacea_web/live/commander/sites_live/edit.ex#L87
That means there are no validation errors in the form itself, right? Just the existing No Such Resource warning when it attempts to save, which seems to have something to do with acting across api boundariesOh so you're still getting that issue?
That one?
Yes, despite being on ash main
Okay, does the warning include a stack trace?
Does everything work if you manually specify the api, like you did here? https://discord.com/channels/711271361523351632/1099572167638794290/1100330595042734170
All I get are a ton of teal debug messages for the ash/ecto transactions, and then on form submit the yellow [warning]
The page does not redirect or crash
I'm currently manually specifying the api like that in the Site resource:
https://gitlab.com/avoh-labs/panacea/-/blob/main/lib/panacea/sites/resources/site.ex#L136
Okay. Iβll be back at my laptop in a bit and will build a proper reproduction and finish this once and for all π
π please let me know if there's anything I can provide to track down what's going on, thank you!!
just to confirm
SitesUsers
is part of the Sites
registry
you didn't move it or anything when debugging?I have not moved it since its creation, it has always been under the Sites api
the Accounts api is pretty much wholesale the one from the auth documentation, then I tried to tie it into Sites with a cross-api many-to-many following the tags examples i found in this discord, and the join relationship is specified under Sites
yeah, okay now that I'm at my laptop, this is all much clearer
I have a plan that will simplify all of this π
okay, try ash main π
What it should do is give you compile time error messages if its misconfigured, and in your case should tell you to define the join relationship (although I think you already have, so this might just fix the issue)
compiling π
I'm still seeing the same message on submit if I add a user:
I deleted the build directory, deleted dependencies, recompiled, it says it pulled ash
Your commit looks like documentation changed as well so I'm reading back through that trying to see what I have set up incorrectly
Did you do
mix deps.update ash
to update the lock to the latest commit?
Thatβs the only way to make it use the latest version of a git dependencyCOMPILE ERROR OKAY
i didn't realize there was any version tracking going on under the hood beyond specifying
origin/main
π i'll remember that.
beautiful error! working through this now
ah, I messed up the error message
That should say
many_to_many
relationship :the_many_to_many_name
I'm not sure what it's saying, in the error the the through resource is the same as the destination resource?
or because the join resource is not accepted by the accounts api, do I have to define something under the accounts api to make it accept it?
How are you defining the join relationship currently?
Do you have a
has_many
relationship set up for the many_to_many
?
or are you letting it do it automatically?The Site has the relationships defined
https://gitlab.com/avoh-labs/panacea/-/blob/main/lib/panacea/sites/resources/site.ex#L136
through a join resource called SitesUsers
https://gitlab.com/avoh-labs/panacea/-/blob/main/lib/panacea/sites/resources/sites_users.ex#L21
Something wasn't working with the relationship initially, so I added that join resource based on some examples I found here to do with posts and tags, i think I have the link as a comment in there still. My understanding was that it's supposed to kind of automatically intuit what's going on but in my case it needed an explicit join resource
got it
So you haven't actually connected the relationships
you want to add
join_relationship :sites_users
got it π€¦ With that addition I can successfully persist users to the database and they show up from queries in iex. just gotta figure out what I need to do to show the existing ones in the form
You probably need to load the relationship on the data
before creating your form
It's being loaded along with the other working resources in handle_params on the edit action. Am I right to suspect the form might need some manual work?
edit.ex
I don't think so
You're using "inputs for" to loop over each nested form right?
Yes, inputs_for here:
https://gitlab.com/avoh-labs/panacea/-/blob/main/lib/panacea_web/live/commander/sites_live/edit.html.heex#L23
Loading here:
https://gitlab.com/avoh-labs/panacea/-/blob/main/lib/panacea_web/live/commander/sites_live/edit.html.heex#L23
Loading with the same code works in iex but not in show.ex or edit.ex,
IO.inspect
ing there shows a blank users list. Could it be a policies thing?yes, it definitely could be π
Try passing
authorize?: false
when loading
if you get the full list then its a policies thingYes that was it! confirmed policies issue