How to: DateTime validation with compare/2

Im trying to compare datetime in an action with compare/2. Code looks like this:
validate compare(:resumes_at, greater_than: DateTime.utc_now(:microsecond)),
message: "resumes_at must be in the future",
where: [present(:resumes_at)]
validate compare(:resumes_at, greater_than: DateTime.utc_now(:microsecond)),
message: "resumes_at must be in the future",
where: [present(:resumes_at)]
Weird thing is this validation fails even when resumes_at is in the future. Does this work or are there other ways of easily comparing datetimes in inline changes?
4 Replies
ZachDaniel
ZachDaniel2y ago
Interesting...we probably need to make compare use Comp 🙂 You can always create a manual validation oh, actually, in your case, DateTime.utc_now(:microsecond) is always "when the app was compiled" because its in the compile time DSL I'd suggest
defmodule DateInTheFuture do
use Ash.Resource.Validation

def validate(changeset, opts) do
case Ash.Changeset.fetch_argument_or_attribute(opts[:field]) do
{:ok, value} ->
if DateTime.after?(....) do
:ok
else
{:error, field: opts[:field], message: "must be in the future"}
end
:error ->
:ok
end
end
end
defmodule DateInTheFuture do
use Ash.Resource.Validation

def validate(changeset, opts) do
case Ash.Changeset.fetch_argument_or_attribute(opts[:field]) do
{:ok, value} ->
if DateTime.after?(....) do
:ok
else
{:error, field: opts[:field], message: "must be in the future"}
end
:error ->
:ok
end
end
end
Then you can say validate {DateInFuture, field: :resumes_at}, where: [present(:resumes_at)]
gordoneliel
gordonelielOP2y ago
Doesnt look like fetch_argument_or_attribute exists, should I be using get_argument_or_attribute?
ZachDaniel
ZachDaniel2y ago
ah, yeah, you can do that 👍 it will return nil or the value, though otherwise it would be like case fetch_argument(...), .... case fetch_attribute(....), ...
gordoneliel
gordonelielOP2y ago
Thanks, this worked! 🙏

Did you find this page helpful?