json - Elixir - 将 http 响应 json 转换为 ecto.schema 对象
问题描述
我是长生不老药的新手。我有一个 Ecto Schema
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://localhost:8080/getScoreData
提供数据的 HTTP REST API
{
"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
而不是真的OverallScore
ecto
schema object
解决方案
我建议不要使用“as:[%OverallScore{}]”语法,而是使用模型中已有的变更集。这看起来像这样:
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 repo 将其插入数据库。
推荐阅读
- python - 如何基于“对象”声明类
- angular - 在 mat table angular 中显示类别名称而不是 id
- firebase - Firebase IDToken 到 Unity 中的 Google OAuth2 访问令牌
- angular - Angular 服务失败
- awk - 如何使用 yq 更改嵌套 YAML 记录中的值
- c# - 按钮设置可见后代码不会反映在 UI 上
- typescript - 在 Jest 中使用 setTimeout 函数测试 vue 组件
- vue.js - vue中的数据绑定不更新
- python - 使用带有 flask_smorest 和/或 marshmallow 的自定义解析器
- yocto - unzip-native 的作用是什么?