【问题标题】:How to type cast decode JSON as if it came from the database如何键入转换解码JSON,就好像它来自数据库一样
【发布时间】:2015-01-21 19:15:37
【问题描述】:

从数据库加载日期/时间类型时,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}

【问题讨论】:

    标签: elixir ecto


    【解决方案1】:

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

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

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

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

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

    然后在您的架构中:

    timestamps type: Rocket.DateTime
    

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

    【讨论】:

    • 感谢自定义类型的链接,如果数据可信,这仍然是首选方法吗?在这种情况下,JSON 用于序列化/反序列化模型,以便不同语言的程序可以处理数据
    • 即使数据是可信的,这也是双向的。 :) 所以你很好。
    • 这仍然有效吗,cast 返回一个变更集,然后我需要应用它来获取模式,似乎很昂贵Ecto.Changeset.cast(Poison.decode!(data), %Rocket.User{}, ~w(required_fields), ~w(optional_fields)) |> Ecto.Changeset.apply_changes
    猜你喜欢
    • 1970-01-01
    • 2017-12-28
    • 2022-08-19
    • 1970-01-01
    • 1970-01-01
    • 2021-06-05
    • 2013-03-14
    • 2022-08-19
    • 1970-01-01
    相关资源
    最近更新 更多