Elixir中的自定义类型

时间:2016-08-23 15:24:53

标签: elixir ecto

我有一个玩具项目,我用来帮助我学习Elixir / Phoenix。

我从csv导入一些数据,如果根据我的变更集有效,我想将这些记录插入到数据库中。

我的问题是,有时其中一个通常包含整数的列将具有" n / a"。这会导致变更集无效,应该如此。

我不确定Elixir标准的处理方法是什么。

在这些情况下,我只想要" n / a"转换为0.

您通常会为此进行转换吗?

https://hexdocs.pm/ecto/Ecto.Type.html

在Rails中,我可以使用自定义setter或在before_save中的模型上解决此问题。

1 个答案:

答案 0 :(得分:4)

我会在模型的changeset函数中通过“修复”params,然后将其发送到cast进行验证来执行此操作。

具有:count整数字段的示例模型:

def changeset(struct, params \\ %{}) do
  struct
  |> cast(fix_params(params), [:count])
  |> validate_required([:count])
end

defp fix_params(%{count: "n/a"} = params), do: %{params | count: 0}
defp fix_params(params), do: params

演示:

iex(1)> Counter.changeset(%Counter{}, %{count: 123})
#Ecto.Changeset<action: nil, changes: %{count: 123}, errors: [],
 data: #MyApp.Counter<>, valid?: true>
iex(2)> Counter.changeset(%Counter{}, %{count: "n/a"})
#Ecto.Changeset<action: nil, changes: %{count: 0}, errors: [],
 data: #MyApp.Counter<>, valid?: true>
iex(3)> Counter.changeset(%Counter{}, %{count: "foo"})
#Ecto.Changeset<action: nil, changes: %{},
 errors: [count: {"is invalid", [type: :integer]}], data: #MyApp.Counter<>,
 valid?: false>

如果您想将任何非整数值转换为0,您可以这样做:

defp fix_params(%{count: count} = params) when not is_integer(count), do: %{params | count: 0}
defp fix_params(params), do: params

演示:

iex(1)> Counter.changeset(%Counter{}, %{count: "foo"})
#Ecto.Changeset<action: nil, changes: %{count: 0}, errors: [],
 data: #MyApp.Counter<>, valid?: true>