How to input data for many-to-many nested associations in the LiveView template?

Hello there. I have two schemas, which have an M:M relation

schema “users_details” do

fields

many_to_many :interests, Project.Accounts.Interests, join_through: “users_details_interests”

schema “interests” do
field :tag, :string
many_to_many :users_details, Project.Accounts.UserDetails, join_through: “users_details_interests”
timestamps()
end

And I have join table, which i create in migration:

create table(:users_details_interests) do
  add :user_details_id, :bigint
  add :interests_id, :bigint
  timestamps()
end

How I can input data for interests table in phoenix template?
I tried doing it the way I did for the 1:1 relationship, no errors, but no new fields appeared in the template.

<%= form_for @details_changeset, “#”,

[phx_change: :details_validate, phx_submit: :details_save, phx_hook: “SavedForm”], fn f-> %>

<%= inputs_for f, :interests, fn f2 → %>
<%= label f2, :tag %>
<%= text_input f2, :tag, phx_debounce: “blur” %>
<%= error_tag f2, :tag %>
<% end %>

<%= submit "Save", phx_disable_with: "Saving..." %>
<% end %>

However, inputs_for sees the interests table, because if i change “:interests” to something else (e.g. “:test”) in “inputs_for”, i get an error

<%= inputs_for f, :test, fn f2 → %>
<%= label f2, :tag %>
<%= text_input f2, :tag, phx_debounce: “blur” %>
<%= error_tag f2, :tag %>
<% end %>

could not generate inputs for :test from Project.Accounts.UserDetails. Check the field exists and it is one of embeds_one, embeds_many, has_one, has_many, belongs_to or many_to_many

Usually I would use multiple checkboxes to join many to many.

But in your case, it seems You also want to create interest at the same time You create a user.

Under the hood, it looks like a tagging system.

And there is a good example here…

https://hexdocs.pm/ecto/constraints-and-upserts.html

Thats nice example, but for now I just can`t show my table interests fields in the template.

<%= form_for @details_changeset, “#”,

[phx_change: :details_validate, phx_submit: :details_save, phx_hook: “SavedForm”], fn f-> %>

<%= inputs_for f, :interests, fn f2 → %>
<%= label f2, :tag %>
<%= text_input f2, :tag, phx_debounce: “blur” %>
<%= error_tag f2, :tag %>
<% end %>
<%= submit "Save", phx_disable_with: "Saving..." %>
<% end %> 

in code above i showed part of my template. The problem is field doesnt show on my page. And i cant get it: it`s because of my ecto part error or phoenix part error.

Probably because there are no interests to show…

That’s why inputs_for shows nothing.

I want to display an input field where I can enter tags to write them into the database, but this input field is not displayed. I realized that I need to write a parser to break up the tags written with commas, but the problem is that I don’t have anywhere to enter the tags. Accordingly, I cant add a handle event that will track this field because the field just doesnt exist at page.
I hope I’ve made it clear what I mean.

It was clear enough… but inputs_for is not the input I would use.

In fact, I would use a virtual field, with a simple text input :slight_smile:

The virtual field is where You enter your comma delimited tags.

1 Like