我有一个包含field :owned_by_id, :string
的Ecto架构。我声明该字段是一个字符串,因为我需要支持像“abc123”这样的值以及像“123”这样的值。
第二个参数是根据
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
处理这个问题?有没有办法让它自动处理?
答案 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