【发布时间】:2020-06-30 23:33:02
【问题描述】:
我在尝试实施自定义变更集验证时遇到了一些麻烦。 我的架构是:
defenum(VersionStateEnum, ["draft", "active"])
schema "versions" do
field :expires_at, :utc_datetime
field :state, VersionStateEnum
end
我正在尝试实施的验证是:只有在状态为草稿时才能设置 expires_at(这也应该对更新有效,如果状态仍然是草稿,我应该无法删除 expires_at) 我尝试了以下方法:
defp validate_expires_at(changeset) do
expires_at = get_change(changeset, :expires_at)
cond do
get_change(changeset, :state) == :draft ->
case expires_at do
nil -> add_error(changeset, :expires_at, "can't be blank when state is draft")
_ -> changeset
end
get_change(changeset, :state) == :active ->
case expires_at do
nil -> changeset
_ -> add_error(changeset, :expires_at, "cannot be set when state is not draft")
end
true ->
changeset
end
end
end
但它并没有真正起作用,因为即使状态是草稿,我也可以将 expires_at 更新为 nil。任何帮助表示赞赏。
编辑 1: 我的变更集:
@required_fields [
:state
]
@optional_fields [:expires_at]
def changeset(model, params \\ nil) do
model
|> cast(params, @required_fields ++ @optional_fields)
|> validate_required(@required_fields)
|> validate_expires_at()
end
在哪里调用:
def create_document(attrs \\ %{}) do
%Document{}
|> Document.changeset(attrs)
|> Repo.insert()
end
【问题讨论】:
-
变更集中的更改是否包括
state的值作为原子还是字符串? -
如果它作为原子传递给变更集。
-
你能发布你的变更集函数以及你更新它的代码吗?
-
那你什么时候更新呢?我试图重新创建问题,但如果我尝试将其创建为“草稿”,它会将错误添加到变更集中。在您说即使是草稿也可以更新
expires_at的问题中,您能否还包括您用于更新它的代码?如果你只是做create_document(%{state: "draft"}),它是否成功插入,因为我试过了,它确实返回了一个错误的变更集 -
我的意思是状态已经是草稿并且已设置 expires_at,如果您尝试将 expires_at 更新为 nil 它将起作用,但它不应该起作用,因为它是没有 expires_at 的草稿在这种情况下没有意义。这有意义吗?
标签: elixir ecto phoenix changeset