如何键入cast decode JSON,就好像它来自数据库一样

时间:2015-01-21 06:11:26

标签: elixir ecto

从数据库加载日期/时间类型时,Ecto将转换为Ecto.DateTime类型。从JSON字符串

加载模型时,如何应用相同类型的转换
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 个答案:

答案 0 :(得分:6)

如果您使用的是Ecto 0.6.0,最好的方法是使用更改集:

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

如果您将此作为外部数据接收,则实际建议使用changeset,因为您需要在将此数据添加到模型之前对其进行强制转换,过滤和验证。您可以在Ecto.Changeset模块文档中找到有关它们的更多信息in the Ecto introduction

虽然还有一个问题:Ecto不知道如何将字符串转换为日期时间。但是,您可以通过使用自定义类型来教它如何使用。我在下面创建了一个模板,你只需要实现一个转换函数:

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

然后在你的架构中:

timestamps type: Rocket.DateTime

您可以在Ecto.Type文档中找到更多信息。我知道我们需要在Ecto中改进它,我认为我们至少应该能够以JSON中指定的格式解析日期时间。