I generated a Todo app with Phoenix generators.
Schema for todo list
defmodule MyApp.Todos.TodoList do
use Ecto.Schema
import Ecto.Changeset
schema "todo_lists" do
field :title, :string
has_many :todo_items, MyApp.Todos.TodoItem
timestamps()
end
@doc false
def changeset(todo_list, attrs) do
todo_list
|> cast(attrs, [:title])
|> validate_required([:title])
|> cast_assoc(:todo_items)
end
end
Schema for todo items
defmodule MyApp.Todos.TodoItem do
use Ecto.Schema
import Ecto.Changeset
schema "todo_items" do
field :description, :string
belongs_to :todo_list, MyApp.Todos.TodoList
timestamps()
end
@doc false
def changeset(todo_item, attrs) do
todo_item
|> cast(attrs, [:description])
|> validate_required([:description])
end
end
And the Liveview form
<div>
<h2><%= @title %></h2>
<.form
let={f}
for={@changeset}
id="todo_list-form"
phx-target={@myself}
phx-change="validate"
phx-submit="save">
<%= label f, :title %>
<%= text_input f, :title %>
<%= error_tag f, :title %>
<%= inputs_for f, :todo_items, fn item_form -> %>
<%= label item_form, :description %>
<%= text_input item_form, :description %>
<%= error_tag item_form, :description %>
<% end %>
<div>
<%= submit "Save", phx_disable_with: "Saving..." %>
</div>
</.form>
</div>
The LiveView form is not rendering fields from the todo_items
schema, it’s only rendering the fields in the todo_list
schema.
Screenshot for todo list form:
However, if I change the relation from has_many
to has_one
, like this has_many :todo_items, MyApp.Todos.TodoItem
to has_one :todo_items, MyApp.Todos.TodoItem
the fields from the related todo_items
schema are shown in the form. See the screenshot below:
Not sure what am doing wrong because I know that adding cast_assoc(:todo_items)
to the todo_list
changeset should take care of rendering relationships in the forms.
For reference look this example from ecto
docs: Polymorphic associations with many to many — Ecto v3.11.2