How to insert multiple records like this [%{name: "Name, user_id: user_id, comments: [%{name: name}],...]

Hello all,

I have those schemas:

User:

@primary_key {:id, :binary_id, autogenerate: true}

  schema "users" do
    field :name, :string

    has_one :repository, Repository
    has_many :contributors, Contributor
    has_many :issues, Issue

    timestamps()
  end

Issue:

@primary_key {:id, :binary_id, autogenerate: true}

  schema "issues" do
    field :author, :string
    field :title, :string

    belongs_to :user, User, type: :binary_id
    has_many :labels, Label

    timestamps()
  end

Label:

@primary_key {:id, :binary_id, autogenerate: true}

  schema "labels" do
    field :name, :string

    belongs_to :issue, Issue, type: :binary_id

    timestamps()
  end

And all I want to do is to use a list of issues, like this:

[%{author: "Samuel", title: "Title", labels: [%{name: "Label"}], ...]

And insert it in a Multi:

Multi.new()
|> Multi.insert(:user, %User{name: user})
|> Multi.insert_all(:issues, Issue, fn %{user: user} ->
      issues
      |> Enum.map(fn issue ->
        Map.put(issue, :user_id, user.id)
      end)
end)
|> Repo.transaction()

When I run like this I get an error that the field labels does not exist in Issue. But then I even tried to take it off, but then the Multi also fail saying that I can’t insert associations. But I did just like the example in the documentation. I tried different approaches but I can’t get it to work.

Thanks in advance for the help,

From the documentation for Repo.insert_all:

It is also not possible to use insert_all to insert across multiple tables, therefore associations are not supported.

insert_all builds a single SQL INSERT statement and has all the requirements and limitations of that.

If anyone is interested, the code bellow resolved my problem:

|> Multi.merge(fn %{user: user} ->
      Enum.reduce(issues, Multi.new(), fn issue, multi ->
        issue = %Issue{
          author: issue.author,
          title: issue.title,
          labels: issue.labels,
          user_id: user.id
        }

        Multi.insert(multi, {:issue, issue}, issue)
      end)
    end)