Right now save (or save!) encapsulates the selection between a put and an update, with the ability to force put. I recently wanted a "find or create" method, and naively did:
record = MyRecord.find(key: 123)
record ||= MyRecord.new(key: 123)
...
record.save! #=> Conditional write exception
I end up receiving the conditional write exception because some other process is trying to create the same record.
To fix this, I moved to using an update:
MyRecord.update(key: 123, value: 'some new data')
However, we have a GSI which is dynamically generated from the values which update never takes into account (see issue #58). Thus, the preferred solution would be:
MyRecord.new(key: 123, value: 'some new data').upsert!
To achieve this I copied the else statement from ItemOperations#_perform_save which builds an update request for dirty columns and creates the record if it does not already exist; hence upsert.
Right now
save(orsave!) encapsulates the selection between a put and an update, with the ability to force put. I recently wanted a "find or create" method, and naively did:I end up receiving the conditional write exception because some other process is trying to create the same record.
To fix this, I moved to using an update:
However, we have a GSI which is dynamically generated from the values which
updatenever takes into account (see issue #58). Thus, the preferred solution would be:To achieve this I copied the
elsestatement fromItemOperations#_perform_savewhich builds an update request for dirty columns and creates the record if it does not already exist; henceupsert.