我如何预加载关联并将其返回到ecto?

asi*_*niy 4 elixir ecto

假设我有一个User模型has_many Post.

我抓了一个用户:

user = Repo.get(User, 1)
Run Code Online (Sandbox Code Playgroud)

现在我想得到这个用户的所有帖子.我找到的唯一解决方案是:

posts = Repo.preload(user, :posts).posts
Run Code Online (Sandbox Code Playgroud)

但它很难看.那有什么简写吗?

Dog*_*ert 8

您可以使用Ecto.assoc/2获取所有帖子的查询,然后将其传递Repo.all/1给实际获取它们:

iex(1)> user = Repo.get(User, 1)
iex(2)> Ecto.assoc(user, :posts)
#Ecto.Query<from p in MyApp.Post, where: p.user_id == ^1>
iex(3)> Ecto.assoc(user, :posts) |> Repo.all
[debug] QUERY OK source="posts" db=2.4ms
SELECT p0."id", p0."title", p0."user_id", p0."inserted_at", p0."updated_at" FROM "posts" AS p0 WHERE (p0."user_id" = $1) [1]
...
Run Code Online (Sandbox Code Playgroud)

  • 请注意,`preload/2` 在一个数据结构中同时返回父记录(在本例中为用户)和相关记录(posts),而通过管道传输到 `Repo.all` 的 `assoc/2` 只返回相关记录(posts) )。这意味着如果您需要父记录,您可以单独“获取”它们(如上例所示),但如果您将其完全编写为管道语句,您将不会拥有该数据。 (2认同)

Zub*_*abi 5

user = Repo.get(User, 1) |> Repo.preload([:posts])
Run Code Online (Sandbox Code Playgroud)

  • 虽然此代码可能会回答这个问题,但添加代码功能的解释通常被认为是很好的做法。这使得不熟悉该领域的开发人员可以了解代码中发生的情况,并帮助他们学习如何在将来自己解决问题。 (2认同)