Ecto基于自定义键字段名称加入

问题描述 投票:1回答:1

我想让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
elixir ecto
1个回答
1
投票

您可以使用:onjoin选项显式设置要加入的字段。

尝试类似的东西:

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_listsid,在下一行,它指的是:sg_users的一个。

如果你想使用:sg_list:sg_users中的不同字段,你应该把它们放在:id上,并用i.list_id替换SgListItems作为正确的字段

这应该工作。

您甚至可以为:on选项添加多个条件,例如:

on: [id: i.user_id, other_field: i.other_field]也会奏效。但我认为你需要的就像上面的代码片段一样。

© www.soinside.com 2019 - 2024. All rights reserved.