elixir - 基于自定义键字段名称的 Ecto Join
问题描述
我正在尝试join
使用 Ecto 开始工作。Ecto 似乎默认将“id”作为连接条件的关键字段。尝试使用架构中的外键设置将其更改为 list_id 和 user_id,但它似乎不起作用。我错过了什么?
query =
from(i in SgListItems,
join: l in assoc(i, :sg_lists),
join: u in assoc(i, :sg_users),
select: [l.list_id, i.item_id]
)
被翻译成
SELECT s1."list_id", s0."item_id" FROM "sg_list_items" AS s0 INNER JOIN "sg_lists" AS s1 ON **s1."id"** = s0."list_id" INNER JOIN "sg_users" AS s2 ON **s2."id"** = s0."author_id" ) []
例如 sg_lists 的架构如下:
@primary_key {:list_id, :binary_id, autogenerate: true}
schema "sg_lists" do
field(:list_title, :string, null: false)
field(:list_description, :map, null: false)
has_many(:sg_list_items, MyApp.SgListItems, foreign_key: :list_id)
timestamps()
end
sg_list_items 的架构如下。
@primary_key {:item_id, :binary_id, autogenerate: true}
schema "sg_list_items" do
belongs_to(:sg_lists, MyApp.SgLists, foreign_key: :list_id, type: :binary_id)
field(:item_hierarchy, :map, null: false)
field(:item_title, :string, null: false)
field(:item_description, :map, null: false)
belongs_to(:sg_users, MyApp.SgUsers, foreign_key: :author_id, type: :binary_id)
timestamps()
end
解决方案
:on
您可以使用 的选项显式设置要加入的字段join
。
尝试类似:
query =
from(i in SgListItems,
join: l in assoc(i, :sg_lists), on: [id: i.list_id],
join: u in assoc(i, :sg_users), on: [id: i.user_id],
select: [l.list_id, i.item_id]
)
在这一行:[id: i.list_id]
,id
指的是:sg_lists
's id
,在下一行,它指的是:sg_users
's 。
如果您想使用:sg_list
or中的不同字段:sg_users
,您应该将它们替换为:id
,并替换i.list_id
为正确的字段SgListItems
这应该有效。
您甚至可以向:on
选项添加多个条件,例如:
on: [id: i.user_id, other_field: i.other_field]
也可以。但我认为你需要的就像上面的片段一样。
推荐阅读
- unit-testing - 在 go test 文件中使用包级变量
- reactjs - 使用deck.gl和nebula.gl的特定geojson URL在我的反应应用程序中不起作用
- python - 我通过 python 从 Xor 门得到了奇怪的结果
- laravel - Laravel 和 vue 路由器
- python - Apply on pandas groupby 尝试通过其他组
- react-native - 更新到 SDK 36 后 Expo 应用程序在启动时崩溃
- flutter - 如何在 Flutter 中录制时创建音频波?
- javascript - 重绘/重新渲染后如何保持dc-tableview.js(DC.js,数据表)排序?
- mysql - 如何递归检索自动引用的行
- html - 如何在html设计界面中添加线条?