为什么Ecto的`cast`没有将整数转换为字符串?

时间:2016-11-15 15:24:24

标签: elixir ecto

我有一个包含field :owned_by_id, :string的Ecto架构。我声明该字段是一个字符串,因为我需要支持像“abc123”这样的值以及像“123”这样的值。

docs for cast/3说:

  

第二个参数是根据data的类型信息投射的参数图。

在我的模块中,我将changeset定义为:

def changeset(struct, params \\ %{}) do
  cast(struct, params, [:owned_by_id])
end

当我这样做时:

MyModule.changeset(%MyModule{}, %{owned_by_id: 1})

...我希望cast根据owned_by_id声明将field整数参数转换为字符串。

但是,我得到的是包含

的变更集
errors: [owned_by_id: {"is invalid", [type: :string]}]

我可以自己致电Integer.to_string(1),但不应该cast处理这个问题?有没有办法让它自动处理?

2 个答案:

答案 0 :(得分:3)

虽然文档确实说根据类型信息""转换,但是Ecto没有为Integer实现转换 - >串。我的猜测是因为这很少需要,而String - >当输入通过Web表单发送时,整数转换非常有用,其中所有字段都以字符串形式到达。

如果您想要进行此类转换,可以创建自定义类型。该文档有一个自定义类型的示例,它实现了类似的东西:https://github.com/elixir-ecto/ecto/blob/d40008db48ec26967b847c3661cbc0dbaf847454/lib/ecto/type.ex#L29-L40

您的类型将类似于:

def type, do: :string

def cast(integer) when is_integer(integer) do
  {:ok, Integer.to_string(integer)}
end
def cast(string) when is_binary(string), do: {:ok, string}
def cast(_), do: :error

...

注意:我不建议这样做。在我看来,明确的转换会更简单,除非你正在实施一些复杂的东西,比如我上面链接的文档示例。

答案 1 :(得分:0)

如果您需要即插即用解决方案,可以使用我创建的此十六进制包。 https://github.com/luizParreira/ecto_cast_to_string