【问题标题】:Ecto join query causing (Poison.EncodeError) unable to encode valueEcto 连接查询导致 (Poison.EncodeError) 无法编码值
【发布时间】:2017-04-22 10:50:53
【问题描述】:

我有 3 张桌子:

  1. 类别
  2. 子类别
  3. 类别子类别

1 个类别有 0 到多个子类别。

我有这个函数,它从类别表中获取所有条目,并且只获取属于 ID 为 1 的类别的子类别表的条目:

  def getCategories(conn) do
    categories = all Api.Category
    groceryItemSubcategories = from s in Api.Subcategory,
    join: cs in Api.CategorySubcategory, on: cs.c_id == 1,
    select: %{name: s.name, foo: cs.c_id}
    conn
    |> put_resp_content_type("application/json")
    |> send_resp(200, Poison.encode!(%{categories: categories, groceryItemSubcategories: groceryItemSubcategories}))
  end

给出这个错误:

23:10:27.169 [error] #PID<0.339.0> running Api.Router terminated
Server: localhost:4000 (http)
Request: GET /categories
** (exit) an exception was raised:
    ** (Poison.EncodeError) unable to encode value: {"subcategories", Api.Subcategory}
        (poison) lib/poison/encoder.ex:383: Poison.Encoder.Any.encode/2
        (poison) lib/poison/encoder.ex:227: anonymous fn/4 in Poison.Encoder.Map.encode/3
        (poison) lib/poison/encoder.ex:228: Poison.Encoder.Map."-encode/3-lists^foldl/2-0-"/3

        (poison) lib/poison/encoder.ex:228: Poison.Encoder.Map.encode/3
        (poison) lib/poison/encoder.ex:227: anonymous fn/4 in Poison.Encoder.Map.encode/3
        (poison) lib/poison/encoder.ex:228: Poison.Encoder.Map."-encode/3-lists^foldl/2-0-"/3

        (poison) lib/poison/encoder.ex:228: Poison.Encoder.Map.encode/3
        (poison) lib/poison.ex:41: Poison.encode!/2

最后的答案是这样的:

  def getCategories(conn) do
    categories = all Api.Category
    groceryItemSubcategories = Api.Repo.all(from s in Api.Subcategory,
    join: cs in Api.CategorySubcategory, on: cs.s_id == s.id,
    join: c in Api.Category, on: c.id == cs.c_id,
    where: c.id == 1,
    select: %{name: s.name, foo: cs.c_id}
    )
    conn
    |> put_resp_content_type("application/json")
    |> send_resp(200, Poison.encode!(%{categories: categories, groceryItemSubcategories: groceryItemSubcategories}))
  end

使错误消失的部分是将语句包装在Api.Repo.All() 中。 Dogbert 确实是回答这个问题的人,所以我不想回答这个问题。

【问题讨论】:

  • Poison 无法编码元组。尝试选择地图,例如select: {s.name, cs.c_id} -> select: %{name: s.name, foo: cs.c_id}.
  • @Dogbert 谢谢。刚刚发布了我这样做时遇到的错误。
  • 这是一个语法错误。您可以发布您尝试过的整个代码吗?可能在某处缺少逗号或其他内容。
  • @Dogbert 我刚刚将整个函数添加到问题的底部。如果您想查看更多代码,请告诉我。干杯
  • 哦,我的意思是将箭头左侧的代码替换为右侧的代码,而不是复制整个代码。

标签: ecto elixir elixir-poison


【解决方案1】:

原代码主要有两个问题:

  1. 您忘记在第二个查询中调用Repo.all

  2. 您正在查询中选择一个元组,然后将其编码为 JSON。 Poison 确实将元组编码为 JSON。您可以选择列表或地图,具体取决于您想要的数据结构。以下是选择地图的方法:

    groceryItemSubcategories = Api.Repo.all(from s in Api.Subcategory,
      join: cs in Api.CategorySubcategory, on: cs.s_id == s.id,
      join: c in Api.Category, on: c.id == cs.c_id,
      where: c.id == 1,
      select: %{name: s.name, c_id: cs.c_id})
    

【讨论】:

    猜你喜欢
    • 2016-01-21
    • 2018-02-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 2015-04-28
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多