Sometimes we run into concurrency issues with custom fields.
Example is a webhook handler that does this
user_id = params[:externalUserId].split('-')[1]
user = User.find_by(id: user_id)
raise Discourse::NotFound unless user
... do a lot of processing ...
user.custom_fields[:myfield] = params[:whatever]
user.save_custom_fields
When two webhooks fire in rapid succession for the same user, we sometimes end up with a duplicate row. The next time the user custom fields are accessed they look like
{"myfield"=>["value", "value"]}
I see that (user_id, name)
is defined as an index but not unique on user_custom_fields
.
What would be the best pattern to prevent this from happening?