Has anyone found a way to make the Rails model upsert_all
omit those records in the returning
which were neither inserted nor actually changed in an update?
what we’re seeing is that returning
will include all records updated, even if no attributes were actually changed.
we’re trying to bulk update a batch of records, and determine which of those were changed.
thus far, we’ve found a way to do this by passing Arel to the on_duplicate
clause:
TestModel.upsert_all(
...
on_duplicate: Arel.sql("#{TestModel.table_name}.foo = excluded.foo WHERE #{TestModel.table_name}.* IS DISTINCT FROM excluded.*")
)
which inserts the Arel SQL between the generated sql ....DO UPDATE SET
and the ...RETURNING
.