Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Elixir EXTO自定义类型:如何将模型中的字段表示为特定类型?_Elixir_Ecto - Fatal编程技术网

Elixir EXTO自定义类型:如何将模型中的字段表示为特定类型?

Elixir EXTO自定义类型:如何将模型中的字段表示为特定类型?,elixir,ecto,Elixir,Ecto,我有一个模式,我希望其中一个字段以%Cm{value:1.0}(厘米单位)的形式表示 我已定义此自定义类型: defmodule Db.Types.Cm do alias Units.Cm @behavior Ecto.Type def type, do: :float def cast(%Cm{value: integer}) when is_integer(integer) do Cm.new(integer / 1.0) end def cast(va

我有一个模式,我希望其中一个字段以
%Cm{value:1.0}
(厘米单位)的形式表示

我已定义此自定义类型:

defmodule Db.Types.Cm do
  alias Units.Cm

  @behavior Ecto.Type
  def type, do: :float

  def cast(%Cm{value: integer}) when is_integer(integer) do
    Cm.new(integer / 1.0)
  end

  def cast(val = %Cm{value: float}) when is_float(float) do
    val
  end

  def cast(number) when is_float(number), do: Cm.new(number)
  def cast(number) when is_integer(number), do: Cm.new(number / 1.0)
  def cast(_), do: :error

  def load(float) when is_float(float), do: Cm.new(float)

  def dump(%Cm{value: float}) when is_float(float), do: float
  def dump(%Cm{value: integer}) when is_integer(integer), do: (integer / 1.0)
  def dump(_), do: :error
end
遵循文档()中的这些指导原则:

  • type
    应输出数据库类型的名称
  • cast
    应接收任何类型并输出您的自定义EXTO类型
  • load
    应接收DB类型并输出自定义的EXTO类型
  • dump
    应接收自定义的EXTO类型并输出DB类型
以及以下模式:

defmodule Db.Block do
  schema "blocks" do
    field :max_depth, Types.Cm
    timestamps()
  end

  @fields ~w(max_depth)a

  def changeset(struct, params \\ %{}) do
    struct
    |> cast(params, @fields)
  end
end
现在我尝试将块保存到数据库:

defmodule Db.BlockHelpers do
  def new_block(attributes \\ %{}) do
    block = Dict.merge(%{
      max_depth: 2
    }, attributes)

    %Block{}
    |> Block.changeset(block)
    |> Repo.insert!
  end
end

iex> new_block()
...> new_block(%{max_depth: Units.Cm.new(5.0)})
但是,我不断出现错误:

 ** (CaseClauseError) no case clause matching: %Units.Cm{value: 2.0}

我尝试过各种方法的组合,但似乎都做不好。因此,我不能100%确定我是否理解文档


最后,我希望能够传递一个形式为
%Block{max\u depth:%Units.Cm{value:1.0}
的模型结构,其中Cm值作为浮点存储在数据库(postgres)中。

Dogbert提供的正确答案:was返回
值,而不是
{ok,value}

尝试从
Db.Types.cm.cast/1
中的所有成功案例中返回
{:ok,cm}
(其中
cm
%cm{…}
cm.new(…)
)。