问题
I would like to retrieve id from previous inserted table primary key by Ecto Multi.
At first, I insert to A main table. then B details table needs A.id. I tried following code.
Multi.new()
|> Multi.insert(:insert, main)
|> Multi.insert_all(:insert_all, B, details)
|> Repo.transaction()
However I have no idea how to retrieve A.id for insert table B. What I should do for it?
回答1:
You can do something like the following example which creates a new User
record and a new Email
record (where the email
record is associated to the parent user
record via a user_id
foreign key).
alias Ecto.Multi
user = get_user_params_from_form() # <-- or where-ever you are getting data
email = get_email_params_from_form()
Multi.new()
|> Multi.insert(:user, User.changeset(%User{}, user))
|> Multi.insert(
:email,
# Capture the id from the previous operation
fn %{
user: %User{
id: user_id
}
} ->
Email.changeset(%Email{user_id: user_id}, email)
end
)
I think this demonstrates the type of relationship you described. Hope it helps!
回答2:
I think you can use Multi.merge to use the result of the first multi in a second multi.
This is the example from the docs:
multi =
Ecto.Multi.new()
|> Ecto.Multi.insert(:post, %Post{title: "first"})
multi
|> Ecto.Multi.merge(fn %{post: post} ->
# Here, post is the Post inserted in the first multi.
Ecto.Multi.new()
|> Ecto.Multi.insert(:comment, Ecto.build_assoc(post, :comments))
end)
|> MyApp.Repo.transaction()
Update: I've added a comment about the post
(your A
model) that was created in the first multi. You can use post.id
and assign it to the related comments (your B
model).
来源:https://stackoverflow.com/questions/61250436/how-to-retrieve-id-from-previous-inserted-table-key-by-ecto-multi