AshPhoenix Form use for `many_to_many` relationships through `append_and_remove` management

Hi all, and thanks for this amazing project! Today I'm trying to figure out how to use AshPhoenix.Form with field of type {:array, :uuid}, for example in the context of managing a many_to_many relationships through append_and_remove, in extension of your example here https://hexdocs.pm/ash/2.6.18/managing-relationships.html. For example, I have this resources with the desired result of allowing the user to select a list of tags from a multiple select: defmodule Post do use Ash.Resource, data_layer: AshPostgres.DataLayer postgres do table "posts" repo Repo end attributes do uuid_primary_key(:id) attribute(:title, :string) attribute(:content, :string) end relationships do many_to_many :tags, Tag do through PostTag source_attribute_on_join_resource :post_id destination_attribute_on_join_resource :tag_id end end actions do update :set_tags do argument :tags, {:array, :uuid} change manage_relationship(:tags, type: :append_and_remove) end end defmodule Tag do use Ash.Resource, data_layer: AshPostgres.DataLayer postgres do table "tags" repo Repo end attributes do uuid_primary_key(:id) attribute(:name, :string) end relationships do many_to_many :posts, Post do through PostTag source_attribute_on_join_resource :tag_id destination_attribute_on_join_resource :post_id end end end defmodule PostTag do use Ash.Resource, data_layer: AshPostgres.DataLayer postgres do table "post_tags" repo Repo end attributes do uuid_primary_key(:id) end relationships do belongs_to :post, Post, allow_nil?: false belongs_to :tag, Tag, allow_nil?: false, attribute_writable?: true end end With this in place, how can I use AshPhoenix.Form auto-form and/or inputs_for for generating the post[tags][] fields in a clean way?
7 Replies
ZachDaniel
ZachDaniel3y ago
So you’d want a manage_relationship … using the value_is_key option set to :id And then in your form, you’d do inputs_for as normal, setting the id field in the nested form, and it will be transformed before submission to be just the id instead of a map.
moissela
moisselaOP3y ago
Hi @Zach Daniel, thank you for your help but in the meantime I think that I've found the issue and the solution is a little different from your suggestion: let me explain so that maybe we can help someone else in the future through this post. After posting here I've continued trying to resolve my problem and while reading the AshPhoenix source code, I've found this test https://github.com/ash-project/ash_phoenix/blob/main/test/auto_form_test.exs#L33 with this related resource https://github.com/ash-project/ash_phoenix/blob/main/test/support/resources/post.ex#L29 which turn me in the right direction. So in my projects liveview I've replaced the forms: [auto?: true] with forms: AshPhoenix.Form.Auto.auto(Post, :set_tags, include_non_map_types?: true) and now I can use inputs_for form[:tags] with a input nested_form[:id] inside and everything works like expected (in reality I've a LiveComponent that show a dropdown with all the available options and then call add_form and remove_form when user click on the options for creating the sub-forms with only a hidden input for each id). After your response I've tried to replace the resource change manage_relationship(:tags, type: :append_and_remove) with change manage_relationship(:tags, type: :append_and_remove, value_is_key: :id) but this make no difference for the forms: [auto?: true] functionality. So that replace alone don't resolve the issue and with the solution of calling AshPhoenix.Form.Auto.auto I've experimenting that having or not the value_is_key: :id option makes no difference. So maybe should forms: [auto?: true] have the include_non_map_types? true as default? Or maybe can we have something like forms: [auto?: [include_non_map_types?: true, other_opts...]] for cases like these?
ZachDaniel
ZachDaniel3y ago
Ah, right you are. I forgot about that option. 🤔 yeah, I'd have to think about that in terms of making it the default There may be some backwards compatibility issues Could you do me a favor and lodge an issue in the ash_phoenix repo with the information provided above? We can find a way to improve that experience, and maybe that looks like setting a different default value for that field as you suggested.
moissela
moisselaOP3y ago
Oh, right Sure, I will. If you can't make that default for backwards compatibility what about the idea of allowing also a list of opts for auto? instead of true too? For now maybe a little documentation for the include_non_map_types? should be enough
ZachDaniel
ZachDaniel3y ago
can you try ash_phoenix main? It now supports forms: [auto?: [include_non_map_types?: true]] When published to hex/ash_hq it will also show documentation of the available options in the module docs.
moissela
moisselaOP3y ago
Wow, you won! You were so fast that I didn't even have the time to open the issue on github 🚀 I confirm that now works with your latest commit on main 👏 and that value_is_key is not necessary in this case. Le me thank you so much for this project and for you reactiveness and kindness with the community!
ZachDaniel
ZachDaniel3y ago
Glad we got it worked out. LMK if you have any other questions 🙂 And thanks for the kind words.

Did you find this page helpful?