在我的凤凰应用程序中,我有以下架构:
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的新手,所以我想知道是否可以更好地完成某些事情。提前谢谢。
答案 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
,并且两个插入也会在一次交易中自动运行。