gpt4 book ai didi

elixir - Ecto 自定义类型 : How do I represent a field in a model as a specific type?

转载 作者:行者123 更新时间:2023-12-04 20:02:36 25 4
gpt4 key购买 nike

我有一个模式,我希望其中一个字段以 %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

遵循文档中的这些指南 (https://hexdocs.pm/ecto/Ecto.Type.html):

  • type should output the name of the DB type
  • cast should receive any type and output your custom Ecto type
  • load should receive the DB type and output your custom Ecto type
  • dump should receive your custom Ecto type and output the DB type

以及以下架构:

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

现在我尝试将 block 保存到数据库:

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_depth: %Units.Cm{value: 1.0}} 形式的模型结构,其中 cm值作为 float 存储在数据库 (postgres) 中。

最佳答案

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

关于elixir - Ecto 自定义类型 : How do I represent a field in a model as a specific type?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39430717/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com