验证 ISO8601 start_time 在 elixir/ecto/timex 中的 ISO8601 end_time 之前

Validate ISO8601 start_time is before ISO8601 end_time in elixir/ecto/timex

我正在使用 phoenix 处理 json 请求,其中我有 start_time 和 end_time 的 ISO8601 格式,我想验证 end_time 是 > start_time,所以给出:

 {
    "start_time": "2016-07-07T01:00:00+02:00",
    "end_time": "2016-07-07T01:30:00+01:00"
 }

两个字段都应返回验证错误,表示 "start_time":"must be less then end_time" 和 "end_time":"must be greater than start_time"。

使用 ecto 变更集 (+ timex) 实现该目标的首选方法是什么?

您可以编写自定义 vadlidate_time_range 函数并在 changeset 函数的管道内使用它。这些验证器需要将 changeset 结构作为第一个参数和 return changeset 结构。

在此函数中,您需要检查两个日期。如果他们改变了,他们将在 changeset.changes 中。如果没有,您将需要从模型中提取它们。你可以这样得到它们:

start_time = changeset.changes |> Dict.get(:start_time, nil)
start_time = start_time || (changeset.model |> Dict.get(:start_time))
{:ok, start_time} = Timex.parse start_time, "{ISO:Extended}"

结束时间也是如此,因此您可能希望将这三个操作提取到一个函数中。

那你需要和Timex.Comparable.compare(start_time, end_time)比较。

case comparison_result do
  1 ->
    changeset
  _ ->
    changeset
    |> add_error(:start_time, "must be less then end_time")
    |> add_error(:end_time, "must be greater than start_time")
end