Ecto.Multi ussage

时间:2017-05-29 16:27:56

标签: elixir phoenix-framework ecto

在我的凤凰应用程序中,我有以下架构:

defmodule TattooBackend.Accounts.Account do
  schema "accounts" do
    field :email, :string
    field :crypted_password, :string
    field :password, :string, virtual: true
    field :password_confirmation, :string, virtual: true

    timestamps()
  end
end

defmodule TattooBackend.Accounts.Studio do
  schema "studios" do
    field :name, :string

    belongs_to :account, Account

    timestamps()
  end
end

现在我正在尝试编写用于在一个事务中将Account和Studio插入数据库的代码。我正在使用Ecto.Multi来做到这一点。我的代码如下所示:

multi = Multi.new |>
Multi.insert(:account, Account.changeset(%Account{}, %{email: "test@email.com", password: "password", password_confirmation: "password"})) |>
Multi.run(:studio, fn %{account: account} ->
  studio_changeset = Studio.changeset(%Studio{}, %{name: "test", account_id: account.id})
  Repo.insert(studio_changeset)
end)

Repo.transaction(multi)

这段代码完美无缺,但我想知道是否有任何地方可以让它变得更好。我仍然是Elixir的新手,所以我想知道是否可以更好地完成某些事情。提前谢谢。

1 个答案:

答案 0 :(得分:1)

对于此特定代码,您使用put_assoc将新Studio放入Account,然后执行Repo.insert!

Account.changeset(%Account{}, %{email: "test@email.com", password: "password", password_confirmation: "password"})
|> Ecto.Changeset.put_assoc(:studios, [Studio.changeset(%Studio{}, %{name: "test"})])
|> Repo.insert!

put_assoc会在插入之前处理account_id中的Studio,并且两个插入也会在一次交易中自动运行。