Elixir - конвертирует http-ответ json в объект ecto.schema - PullRequest
0 голосов
/ 14 апреля 2020

Я новичок ie для эликсира. У меня есть схема 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 и не совсем OverallScore ecto schema object

1 Ответ

2 голосов
/ 14 апреля 2020

Я бы предложил вместо того, чтобы использовать этот синтаксис "as: [% TotalScore {}]", вы используете набор изменений в своей модели, который у вас уже есть. Это будет выглядеть примерно так:

  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

Наборы изменений - это, как правило, лучший способ получить объекты в экто-структурах, так как они будут правильно проходить проверку вашего набора изменений. Это дает дополнительное преимущество: он удаляет в поле «ответ» все, что не содержится в вызове набора изменений без каких-либо ошибок. Вы также сможете быстро проверить, действителен ли он, и если это так, вы можете вставить его в базу данных с помощью своего экто-репо.

...