How to type cast decode JSON as if it came from the database

六眼飞鱼酱① 提交于 2019-12-06 03:35:48

问题


When loading date/time types from the database, Ecto will cast to a Ecto.DateTime type. How can the same type casting be applied when loading a model from a JSON string

defmodule Rocket.User do
  use Rocket.Model

  schema "users" do
    field :created_at, :datetime
    field :name, :string
    field :email, :string
    field :password, :string
    field :timezone, :string
  end
end

iex(40)> Poison.decode!(~s({"created_at":"2015-01-21T06:05:10.891Z"}), as: Rocket.User)  
%Rocket.User{created_at: "2015-01-21T06:05:10.891Z", email: nil, id: nil,
 name: nil, password: nil, timezone: nil}

回答1:


If you are using Ecto 0.6.0, the best way is to use changesets:

Ecto.Changeset.cast Poison.decode!(data), %Rocket.User{},
                    ~w(required_fields), ~w(optional_fields)

Using changeset is actually recommended if you are receiving this as external data since you need to cast, filter and validate this data before adding it to the model. You can find more information about them in the Ecto introduction and also in the Ecto.Changeset module documentation.

There is one issue left though: Ecto does not know how to cast the string to datetime. You can however teach it how to by using custom types. I have created a template below, you just need to implement the casting function:

https://gist.github.com/josevalim/1ed574b388c32f056da1

Then in your schema:

timestamps type: Rocket.DateTime

You can find more information in Ecto.Type docs. I am aware we need to improve this in Ecto, I think we should at least be able to parse datetimes in the format specified in JSON.



来源:https://stackoverflow.com/questions/28060690/how-to-type-cast-decode-json-as-if-it-came-from-the-database

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!