毒药:无法编码值

时间:2018-04-13 16:42:37

标签: json elixir ecto elixir-poison

我无法对从Ecto查询结果Poison编码方法

获得的值进行编码

控制器代码:

def companies(conn, params) do
    companies = Repo.all(
      from(
        c in Company,
        select: {c.name, c.uid},
        limit: 20
      )
    ) 

    conn
    |> put_resp_header("content-type", "application/json; charset=utf-8")
    |> send_resp(200, Poison.encode!(companies, pretty: true))
end

模板代码:

<div class="form-group row">
  <%= label f, :company_id, class: "control-label" %>
  <%= select f, :company_id, @companies, class: "form-control"%>
<%= error_tag f, :company_id %>

错误讯息:

Request: GET /companies
** (exit) an exception was raised:
    ** (Poison.EncodeError) unable to encode value: {"Loews Corporation", 1000285930}
        (poison) lib/poison/encoder.ex:383: Poison.Encoder.Any.encode/2
        (poison) lib/poison/encoder.ex:268: anonymous fn/4 in Poison.Encoder.List.encode/3
        (poison) lib/poison/encoder.ex:269: Poison.Encoder.List."-encode/3-lists^foldr/2-0-"/3
        (poison) lib/poison/encoder.ex:269: Poison.Encoder.List.encode/3
        (poison) lib/poison.ex:41: Poison.encode!/2

2 个答案:

答案 0 :(得分:2)

Poison无法将元组编码为JSON值。如果您希望在生成的JSON中使用[{name: ..., uid: ...}, {name: ..., uid: ...}],则可以在查询中使用map()select中的地图文字:

select: map(c, [:name, :uid])

select: %{name: c.name, uid: c.uid}

答案 1 :(得分:1)

添加到@ Dogbert的答案:您还可以通过从map手动返回Ecto中生成companies = from(c in Company, select: {c.name, c.uid}, limit: 20) |> Repo.all() # returning list of tuples |> Enum.into(%{}) # this #⇒ %{"Loews Corporation" => 1000285930, "Foo" => 1, "Bar" => 2} 来生成JSON对象:

Poison

可能会使用def example(s): return len(s) sqlContext.udf.register("example_udf", example) spark.sql("SELECT example_udf(col) FROM data") 将地图编码为JSON,从而生成JS对象。