agonzalezro

agonzalezro

Preload associations with cast_embed

Hi :wave:

I had this piece of (working) code:

    items =
      products
      |> Enum.map(fn product ->
        params = %{product_id: product.id}

        Snapshot.new_item_changeset(
          %Snapshot.Item{
            product: product
          },
          params
        )
      end)

That later created a form with:

    form =
      Ecto.Changeset.put_embed(
        Ecto.Changeset.change(%Snapshot{}),
        :items,
        items
      )
      |> to_form

That I was rendering as:

    <.form for={@form} phx-change="validate" phx-submit="save">
      <.inputs_for :let={snapshot} field={@form[:items]}>
        <div><%= snapshot.data.product.description %></div>

However, since I didn’t want to repeat that Ecto.Changeset.put_embed( I wanted to move that logic to the schema as:

  def changeset(snapshot, params \\ %{}) do
    snapshot
    |> cast(params, [])
    |> cast_embed(:items, with: &new_item_changeset/2)
  end

  def new_item_changeset(item, params \\ %{}) do
    item
    |> cast(params, [:quantity, :product_id, :rate_id])
    |> validate_number(:quantity, greater_than_or_equal_to: 0)
  end

But if I move the original code to:

    items =
      products
      |> Enum.map(fn product ->
        %{product_id: product.id}
      end)

And then just:

    form =
      Snapshot.changeset(%Snapshot{}, %{items: items})
      |> to_form

That works, however the template doesn’t have a product loaded ending up in the following error:

key :description not found in: #Ecto.Association.NotLoaded<association :product is not loaded>

It would be easy to fix this with a Repo.preload but since it’s an embedded schema I am not sure where to do that.

Marked As Solved

agonzalezro

agonzalezro

Thanks for the proposals.

I finally fixed my initial issue by also assigning to the socket a map of product id to product:

%{"1" => %xxx.Products.Product{

Then on the form I am showing it as follows:

<div><%= @products[snapshot.params["product_id"] |> to_string].description %></div>

Where Next?

Popular in Questions Top

joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
jononomo
I am trying to figure out how Mix knows whether the environment is test, dev, or prod – where is this set? Thanks.
New
Emily
I have VueJS GUIs with the project generated using Webpack. I have Elixir modules that will need to be used by the VueJS GUIs. I forese...
New
Lily
In templates/appointment/index.html.eex: &lt;%= for appointment &lt;- @appointments do %&gt; &lt;tr&gt; &lt;td&gt;&lt;%= appoi...
New
belgoros
I’m not a pro in using Regex and can’t figure out why the following behaviour happens, especially if we take into account the difference ...
New
freewebwithme
Using vs code and installed ElixirLS: support and debugger. And I got an error popped up on start up says Failed to run ‘elixir’ comma...
New
romenigld
I am trying to run a deploy with docker and I successfully runned with this command: docker build -t romenigld/blog-prod . but when I t...
New

Other popular topics Top

nobody
Hi! In PHP: $_SERVER[‘SERVER_ADDR’] - in Elixir? Searched the docs for ip address and the web, no good results. Thanks!
New
joaquinalcerro
Hi there, I am working with Ecto-Postgresql and I need to call all of the records from a specific table but the table has 40,000 records...
New
JakeBecker
TL;DR: I’ve just released an implementation of Microsoft’s IDE-independent Language Server Protocol for Elixir. It adds language support ...
1144 54921 245
New
lanycrost
Hi everyone! I need implement if…else if…else condition from my elixir code, and anymore of this control flow structures not work proper...
New
joeerl
Hello again - after a longish gap I’ve decided I really must dig into Elixir and see what’s been happening here - so I have a few questio...
New
jason.o
In the code below, if the create action is not set to accept “extra_key” as an input, it errors out with a message shown above. Is there ...
New

We're in Beta

About us Mission Statement