CodexBloom - Programming Q&A Platform

How to avoid duplicating records when using `find_or_create_by` in Ruby on Rails 7.1 with concurrent requests?

👀 Views: 96 đŸ’Ŧ Answers: 1 📅 Created: 2025-06-12
ruby rails activerecord concurrency Ruby

I'm working on a personal project and I'm relatively new to this, so bear with me. I've been struggling with this for a few days now and could really use some help. I'm running into a question with `find_or_create_by` when handling concurrent requests in my Ruby on Rails 7.1 application. I'm trying to create a unique user record based on email, but I'm seeing duplicate entries when two requests are made at the same time. I've implemented the following code: ```ruby class UsersController < ApplicationController def create @user = User.find_or_create_by(email: user_params[:email]) do |user| user.name = user_params[:name] user.password = SecureRandom.hex(8) end if @user.persisted? render json: @user, status: :created else render json: @user.errors, status: :unprocessable_entity end end private def user_params params.require(:user).permit(:email, :name) end end ``` I've tried using a database-level unique constraint on the email field, but I still get `ActiveRecord::RecordNotUnique` errors when two requests hit the endpoint simultaneously. To mitigate this, I attempted to use a lock by wrapping the `find_or_create_by` in a transaction: ```ruby ActiveRecord::Base.transaction do @user = User.find_or_create_by(email: user_params[:email]) do |user| user.name = user_params[:name] user.password = SecureRandom.hex(8) end end ``` Unfortunately, this still doesn't prevent the duplication scenario. I even considered using a Redis lock to handle concurrency, but I'm unsure how to implement that effectively in this context. Has anyone faced a similar scenario or have suggestions for handling this in a Rails application? Any help would be greatly appreciated! This is part of a larger CLI tool I'm building. Has anyone else encountered this? Is there a better approach? Could someone point me to the right documentation? I'm using Ruby stable in this project.