elixir - 如何键入转换解码JSON,就好像它来自数据库一样

标签 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}

最佳答案

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

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

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

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

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

然后在您的架构中:
timestamps type: Rocket.DateTime

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

关于elixir - 如何键入转换解码JSON,就好像它来自数据库一样,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28060690/

相关文章:

elixir - 不要在控制台中截断查询结果

elixir - Phoenix 附加布局变量,例如 @inner

elixir - 使用 Ecto 2.0.0-rc.0 并执行 ecto.migrate 时出现奇怪的错误

elixir - 具有无动于衷的 key 访问的 map

elixir - Elixir 中的协议(protocol)和行为之间的区别

testing - 对 Elixir Ecto 验证测试不起作用的原因感到困惑

postgresql - Phoenix/Elixir - 时间戳不存在,扩展为 timestamps()

elixir - Phoenix Framework - 表单中的确认字段

elixir - 标准化 Elixir/Phoenix 中的字符串

erlang - 如何通过指定模块和方法名称在 Elixir 中动态调用方法?