如何序列化Ecto记录结构使其可以存储为:数据库中的映射?

时间:2017-01-07 16:36:49

标签: elixir ecto

我想存储从Ecto.Schema返回的Repo.get(MyModel, id)结构。

__meta__这样的东西,association: <Association is not loaded>可以阻止jsonifying它,所以我抓住了一个例外(这是合理的)。是否有任何Ecto本机函数只能获取我可以序列化的记录列的映射。存储在数据库中?

3 个答案:

答案 0 :(得分:2)

我的解决方案

defmodule MyApp.Schema do
  @schema_meta_fields [:__meta__]

  def to_storeable_map(struct) do
    association_fields = struct.__struct__.__schema__(:associations)
    waste_fields = association_fields ++ @schema_meta_fields

    struct |> Map.from_struct |> Map.drop(waste_fields)
  end
end

答案 1 :(得分:0)

由于我不知道任何Ecto本机功能,我想你应该使用:

https://hexdocs.pm/elixir/Map.html#from_struct/1

过滤您不想要的按键:

https://hexdocs.pm/elixir/Enum.html#filter/2

并将结果设置为:

https://hexdocs.pm/elixir/Enum.html#into/2

修改:看起来您可以使用&#34; map()&#34;在您的查询中返回地图而不是结构:https://github.com/elixir-ecto/ecto/issues/1348

答案 2 :(得分:-1)

Elixir使您可以派生协议实现:Kernel.defstruct/1

我不确定您使用的是哪种JSON解析器,例如,使用Jason,您可以在其自述文件中找到以下内容:

If you need to encode some struct that does not implement the protocol, if you own the struct, you can derive the implementation specifying which fields should be encoded to JSON:

@derive {Jason.Encoder, only: [....]}
defstruct # ...

Finally, if you don't own the struct you want to encode to JSON, you may use Protocol.derive/3 placed outside of any module:

Protocol.derive(Jason.Encoder, NameOfTheStruct, only: [...])
Protocol.derive(Jason.Encoder, NameOfTheStruct)

也可能会展示如何使用毒药来做到这一点:

When deriving structs for encoding, it is possible to select or exclude specific attributes. This is achieved by deriving Poison.Encoder with the :only or :except options set:

defmodule PersonOnlyName do
  @derive {Poison.Encoder, only: [:name]}
  defstruct [:name, :age]
end

defmodule PersonWithoutName do
  @derive {Poison.Encoder, except: [:name]}
  defstruct [:name, :age]
end
In case both :only and :except keys are defined, the :except option is ignored.