在使用Ecto

问题描述:

使用Ecto v2.2.6中使用中间插入结果的结果在使用Ecto

我有一个博客应用程序。当用户发布帖子时,它将插入到Post表中,然后获取该帖子的结果ID并将其插入到Newsfeeditem表中。理想情况下,我希望这是作为交易发生的。

(我用苦艾酒graphql,所以我对插入返回的形式必须是{:ok, post})的

我有一个工作的功能,看起来像这样:

def create_post_add_newsfeed(%{ 
     title: title, 
     content: content, 
     user_id: user_id 
    }) do 

    case Repo.insert!(%Post{title: title, content: content, user_id: user_id}) do 
     post -> 
     case Repo.insert!(%Newsfeeditem{type: "user_creates_post", user_id: user_id, post_id: post.id}) do 
      newsfeeditem -> 
      {:ok, post} 
      _ -> 
      {:error, "Post not recorded in newsfeed"} 
     end 
     _ -> 
     {:error, "Post not inserted"} 
    end 
    end 

此代码是不是交易,并且它回调恶臭。 Ecto.Multi似乎是一个更适合使用的工具,但我不知道如何获得Post插入的结果,以便我可以将它插入Newsfeed

我愿做这样的事情

不知道如何实现自己的目标?

您可以使用Multi.run/3。传递给Multi.run/3的函数将接收参数所做的更改。您可以从中提取插入的post,并在Multi.run内为Newsfeeditem发出Repo.insert。函数应该返回{:ok, _}{:error, _},这正是Repo.insert返回的内容,所以您不需要在函数内部做更多的事情。

Multi.new 
|> Multi.insert(:post, %Post{title: title, content: content, user_id: user_id}) 
|> Multi.run(:newsfeeditem, fn %{post: post} -> 
    Repo.insert(%Newsfeeditem{type: "user_creates_post", user_id: users_id, post_id: post.id}) 
end)