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

时间:2016-04-22 21:04:33

标签: elixir ecto

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

 {
    "start_time": "2016-07-07T01:00:00+02:00",
    "end_time": "2016-07-07T01:30:00+01:00"
 }
应该为两个字段返回

验证错误,说明" start_time":"必须小于end_time"和" end_time":"必须大于start_time"。

使用ecto changesets(+ timex)实现这一目标的首选方法是什么?

1 个答案:

答案 0 :(得分:1)

您可以编写自定义vadlidate_time_range函数,并在changeset函数中的管道内使用它。那些验证器需要将changeset结构作为第一个参数并返回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