Elixir-将http响应json转换为ecto.schema对象

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

我是长生不老药的新手。我有一个Ecto模式

  defmodule MyScoreSchema do
  use Ecto.Schema
  import Ecto.Changeset

  schema "historical_extra_fuels" do
    field :average, :float
    field :count, :float
    field :percent, :float
    field :name, :string
  end


  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, [:average, :count, :percent])
    |> validate_required([])
  end
end

和父模式

defmodule OverallScore do
  use Ecto.Schema
  import Ecto.Changeset

  schema "OverallScore" do
    field :avg_pass, :float
    field :avg_fail, :float
    field :total_students, :float
    embeds_many :my_score_schema, MyScoreSchema
  end
  @required_fields ~w[]a
  @optional_fields ~w[avg_pass, avg_fail, total_students ]a


  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, @optional_fields, required: false )
    |> cast_embed(:my_score_schema, required: false)
  end
end

并且有一个HTTP REST API http://localhost:8080/getScoreData提供数据

{
      "avgPass": 85.55,
      "avgFail": 14.45,
      "totalStudents": 80.0,
      "myScoreSchema": [
        {
          "average": 80.0,
          "count": 8.0,
          "percent": 80.0,
          "name": "John"
        },
        {
          "average": 90.0,
          "count": 8.0,
          "percent": 90.0,
          "name": "Cena"
        },
        {
          "average": 80.0,
          "count": 8.0,
          "percent": 80.0,
          "name": "Sunny"
        },
        {
          "average": 70.0,
          "count": 8.0,
          "percent": 70.0,
          "name": "Michael"
        }
      ]
    }

和代码

  url = "http://localhost:8080/getScoreData"
   Logger.info("the url is #{url}")
   case HTTPoison.get(url) do
     {:ok, %{status_code: 200, body: body}} ->
       overall_score = Jason.decode!(body, as: [%OverallScore{}])
       {:ok, overall_score}
   end

此方法可以正常工作,并且不会出错,但结果是一些struct而不是真正的OverallScoreectoschema object

elixir ecto elixir-poison httpoison jason
1个回答
0
投票
url = "http://localhost:8080/getScoreData" Logger.info("the url is #{url}") case HTTPoison.get(url) do {:ok, %{status_code: 200, body: body}} -> response = Jason.decode!(body) overall_score = OverallScore.changeset(%OverallScore{}, response) {:ok, overall_score} end

变更集通常是将对象放入ecto结构的最佳方法,因为它们将正确地通过变更集验证运行。这有一个额外的好处,就是它可以将“响应”字段中没有出现在变更集的强制调用中的所有内容删除,没有任何错误。您还可以快速检查它是否有效,如果可以,则可以使用ecto存储库将其插入数据库。

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