adding data to the junction table

How can i add data to a junction/pivot table through a form? I have create action enabled on the junction table
21 Replies
frankdugan3
frankdugan3β€’3y ago
AshPhoenix has some great tooling around that. Please read the docs carefully, because AshPhoenix Forms function a bit differently than Ecto changesets. https://hexdocs.pm/ash_phoenix/AshPhoenix.Form.html#module-working-with-related-data
talha-azeem
talha-azeemOPβ€’3y ago
I did read it but i couldn't get much out of it. That is why i came to support channel
frankdugan3
frankdugan3β€’3y ago
Could you expand a little bit? What did you try, what part of it is confusing specifically?
ZachDaniel
ZachDanielβ€’3y ago
You'll want to look at these docs as well: https://hexdocs.pm/ash/Ash.Changeset.html#manage_relationship/4 Before you try to do it with a form, get it working by calling actions
talha-azeem
talha-azeemOPβ€’3y ago
Is it something like cast_assoc?
ZachDaniel
ZachDanielβ€’3y ago
Yes It works similarly but there are a lot more options/instructions
talha-azeem
talha-azeemOPβ€’3y ago
is there any example in ash-hq?
ZachDaniel
ZachDanielβ€’3y ago
Nope For instance, one of your options might be something like this:
# {:create, destination_action_name, :join_action_name, [:fields, :for, :join]}
on_no_match: {:create, :create, :create, [:list, :of, :join_table, :params]}
# {:create, destination_action_name, :join_action_name, [:fields, :for, :join]}
on_no_match: {:create, :create, :create, [:list, :of, :join_table, :params]}
That would create a destination record, and a join record, passing certain options to the join resource action
talha-azeem
talha-azeemOPβ€’3y ago
I have three tables at the moment. Teams, Users, Team Joined User(junction table) many_to_many relation is defined in teams and users. this is what i have done so far. for this implementation. What i was trying to achieve here was to have a dropdown of user that gets selected and then have a hidden input of team_idand insert it in the junction table but it gives me this in form submit_errors: [team: {"is required", []}, user: {"is required", []}]
form =
user
|> AshPhoenix.Form.for_update(:update,
api: MyApi,
forms: [
profile: [
resource: MyApp.Profile,
data: user.profile,
create_action: :create,
update_action: :update
forms: [
emails: [
data: user.profile.emails,
resource: MyApp.UserEmail,
create_action: :create,
update_action: :update
]
]
]
])
form =
user
|> AshPhoenix.Form.for_update(:update,
api: MyApi,
forms: [
profile: [
resource: MyApp.Profile,
data: user.profile,
create_action: :create,
update_action: :update
forms: [
emails: [
data: user.profile.emails,
resource: MyApp.UserEmail,
create_action: :create,
update_action: :update
]
]
]
])
Do i need to define the form like this instead of normal create one for teamjoineduser? I am not getting it πŸ˜…
ZachDaniel
ZachDanielβ€’3y ago
Have you read the entirety of the documentation about manage_relationship
talha-azeem
talha-azeemOPβ€’3y ago
yeah i am reading it as we talk.
frankdugan3
frankdugan3β€’3y ago
In a nutshell, you're going to create a custom action that 1) accepts args for the relationships, and 2) configure manage_relationship for that action. Then you can use that custom action in the form. Then you can use forms: [auto?: true] and it will be a lot simpler, IMO.
talha-azeem
talha-azeemOPβ€’3y ago
@frankdugan3 action will be defined like we defined code_interface, right?
frankdugan3
frankdugan3β€’3y ago
This is not a many to many, just an example of the kind of thing you'd do:
create :create do
primary? true
argument :type_id, :uuid, allow_nil?: false
argument :employee_id, :uuid, allow_nil?: false

change manage_relationship(:type_id, :type, type: :append_and_remove)
change manage_relationship(:employee_id, :employee, type: :append_and_remove)
end
create :create do
primary? true
argument :type_id, :uuid, allow_nil?: false
argument :employee_id, :uuid, allow_nil?: false

change manage_relationship(:type_id, :type, type: :append_and_remove)
change manage_relationship(:employee_id, :employee, type: :append_and_remove)
end
talha-azeem
talha-azeemOPβ€’3y ago
okay, i think i get it a little. it will be defined in my junction table resource, right?
frankdugan3
frankdugan3β€’3y ago
Then, that gives AshPhoenix the info it needs to do this instead:
form =
user
|> AshPhoenix.Form.for_update(:update,
api: MyApi,
forms: [auto?: true]
form =
user
|> AshPhoenix.Form.for_update(:update,
api: MyApi,
forms: [auto?: true]
Much easier to grep.
talha-azeem
talha-azeemOPβ€’3y ago
I will try it in the morning. Thank you. in the above action i defined it for create and in here you said Form.for_update?
create :create do
primary? true
argument :team_id, :uuid, allow_nil?: false
argument :user_id, :uuid, allow_nil?: false

change manage_relationship(:team_id, :team, type: :append_and_remove)
change manage_relationship(:user_id, :user, type: :append_and_remove)
end


identities do
identity :unique_team_joined, [:user_id, :team_id]
end
create :create do
primary? true
argument :team_id, :uuid, allow_nil?: false
argument :user_id, :uuid, allow_nil?: false

change manage_relationship(:team_id, :team, type: :append_and_remove)
change manage_relationship(:user_id, :user, type: :append_and_remove)
end


identities do
identity :unique_team_joined, [:user_id, :team_id]
end
Defined this in team joined user resource. now it works but two insertions are going at same time I think I am missing something here. @Zach Daniel just wondering which extension you are using for autocomplete in ASH resource? P.s. I just saw your twitter video and you showed the many_to_many relation through the ash admin πŸ˜… I used a different approach for this. After looking at the twitter repo by @Zach Daniel . I made my junction table attributes attribute_writable? true and then added this create action:
create :create do
primary? true
upsert? true
upsert_identity :unique_team_joined
end
create :create do
primary? true
upsert? true
upsert_identity :unique_team_joined
end
and now it works for me.
ZachDaniel
ZachDanielβ€’3y ago
πŸ€” you just wanted to be able to create an instance of the join table? TBH I still don’t really understand exactly what you were trying to do, but I’m glad you got it worked out πŸ‘
talha-azeem
talha-azeemOPβ€’3y ago
basically, i had three tables 1. users 2. teams 3. team joined user (junction table) I wanted to make an addition to junction table through the form.
ZachDaniel
ZachDanielβ€’3y ago
And did you get it worked out with [auto?: true] forms?
talha-azeem
talha-azeemOPβ€’3y ago
yes it is working now

Did you find this page helpful?