gpt4 book ai didi

elixir - Ecto:如何通过选择另一个连接列来预加载记录

转载 作者:行者123 更新时间:2023-12-04 14:39:03 33 4
gpt4 key购买 nike

有没有办法通过选择另一个连接列来预加载记录?

# table structure
# User 1---* Post 1---* PostTag *---1 Tag

# extract definition of scheme
scheme "posts" do
...
has_many :post_tags, PostTag
has_many :tags, [:post_tags, :tag]
end

以下伪代码表达了我的目标(但不起作用)。
query = from post in Post,
join: user in User, on post.user_id == user.id,
select: %{
id: post.id,
title: post.title,
user_name: user.name, # <= column at joined table
},
preload: [:tags]
Repo.all(query)
#=> ** (Ecto.QueryError) the binding used in `from` must be selected in `select` when using `preload` in query:`

我期待这样的结果。
[
%{id: 1, title: "AAA", user_name: "John", tags: [%{name: "elixir"},...]},
%{id: 2, title: "BBB", user_name: "Mike", tags: [%{name: "erlang"},...]},
...
]

最佳答案

正如错误消息所说,您需要选择您在 from 中提供的绑定(bind)。预加载时,否则 Ecto 没有地方放置预加载的标签。这是一个简单的答案:

query = from post in Post,
join: user in User, on: post.user_id == user.id,
select: {post, user.name},
preload: [:tags]
通过返回一个元组,您可以将完整的帖子和用户名放在一边。另一种方法是将 post 和 users 作为完整结构返回:
query = from post in Post,
join: user in User, on: post.user_id == user.id,
preload: [:tags, user: user]
或者如果您不想要所有字段:
query = from post in Post,
join: user in User, on: post.user_id == user.id,
preload: [:tags, user: user],
select: [:id, :title, :user_id, user: [:name]]

关于elixir - Ecto:如何通过选择另一个连接列来预加载记录,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48557128/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com