In a Rails 5 app I create items and increment their position:
class ListItem < ActiveRecord::Base
belongs_to :list
before_validation :ensure_position
private
def ensure_position
self.position ||= self.class.where(list_id: list_id).maximum(:position).to_i + 1
end
end
The index responsible for the duplicate violation is:
t.index ["list_id", "position"]
I get a PG duplicate key violation on the :position column. Whenever multiple create are fired simultaneously, the maximum function returns the same position for multiple records.
I am new to thread safety and postgres locking in ruby on rails. Is there a way to lock or create a mutex on save action of the list item record so that the position gets incremented safely?