There're situations when I need to insert 2 objects of the same Struct into a database, via Ecto, such that inserted_at
or updated_at
of one of the Struct should differ only by 1 second from the other one.
I insert 2 struct objects sequentally, one after right the other, and their inserted_at
and updated_at
turn out to be identical. Whereas I want a 2nd object to have inserted_at
and updated_at
greater by 1 second to a 1st one, so that later on when I retrieve them from a database and show on a page, data will make more sense.
Supplying inserted_at
or updated_at
+ 1 second to a changeset
structure of a 2nd object didn't help because they got ignored by Ecto, and both objects got identical inserted_at
and updated_at
values.
Calling :os.sleep(1000)
between the calls to insert
will be a bad option.
How can I do it?
One might use Ecto.Repo.insert_all/3
for this exact purpose. According to docs:
If the schema contains an autogenerated ID field, it will be handled either at the adapter or the storage layer. However any other autogenerated value, like timestamps, won't be autogenerated when using
insert_all/3
.
That said, one should explicitly set inserted_at
and updated_at
values for both changesets using DateTime.utc_now/0
and then call update_all/3
.
Beware! If your records have other calculated by Ecto fields, all of them should be also set explicitly.
Another option would be to insert both and then alter the second one, but this is definitely worse since it requires 3 queries instead of one in the approach above.