Hi
I am trying to create a live view that shows a form. This form will allow you to create an snapshot per each product you own. The snapshots saves a quantity and a reference to the product.
There is another field rate
that I will remove from the snippets for simplicity:
# snapshot.ex
defmodule xxx.Snapshots.Snapshot do
...
schema "snapshots" do
embeds_many :items, Item do
field(:quantity, :integer)
belongs_to(:product, Product)
timestamps()
end
end
...
def new_item_changeset(snapshot, params \\ %{}) do
snapshot
|> cast(params, [:quantity, :product_id])
|> validate_number(:quantity, greater_than_or_equal_to: 0)
end
end
I have this view:
# dashboard_live.ex
defmodule xxxWeb.DashboardLive do
...
@impl true
def mount(_params, session, socket) do
current_user = Accounts.get_user_by_session_token(session["user_token"])
products = Products.get_by_user!(current_user)
items =
products
|> Enum.map(fn product ->
params = %{product_id: product.id}
Snapshot.new_item_changeset(
%Snapshot.Item{
product: product # preload
},
params
)
end)
form =
Ecto.Changeset.put_embed(
Ecto.Changeset.change(%Snapshot{}),
:items,
items
)
|> to_form
{:ok,
socket
|> assign(:page_title, "Dashboard")
|> assign(form: form |> IO.inspect())
|> stream(:products, products)}
end
def render(%{live_action: :show} = assigns) do
~H"""
<.form for={@form} phx-change="validate" phx-submit="save">
<%= for snapshot <- @form.source.changes.items do %>
<div><%= snapshot.data.product.description %></div>
<%!-- <div><%= product.type %></div> --%>
<.input type="number" field={snapshot[:quantity]} />
<% end %>
<%!-- <%= for item <- @form[:items] do %>
<.input type="number" field={item[:quantity]} />
<% end %>
--%>
<button>Add snapshot</button>
</.form>
"""
end
end
I have several questions here:
- I have added the
embeds_many
in the schema because it was the only way I found to create a form with several changesets. Is it right? - Is
belongs_to
the best way to scheme this? A user has N products where N can be dynamic through time. The snapshot is a snapshot (sorry) of that moment in time adding the quantity of products they own. - I am able to list the product description with
<%= snapshot.data.product.description %>
however I don’t know how to make the<.input />
work as it is a changeset inside a changeset and not a form.
Any other suggestion/help would be more than welcome. I am trying to do this to understand LiveViews so I want to be the closest to the “credo” as possible.
Thanks!