user2274074
user2274074

Reputation: 1087

Rails: ActiveRecord::RecordNotUnique how to find for which column the exception was raised

Currently there is a unique index on my column with name "index_unique_devices_on_dsn" . when i am saving duplicating record i am getting mysql exception and i am handling that exception using class ActiveRecord::RecordNotUnique . if in the future if i am adding multiple columns and each column having its own unique index then how can i programmatically identify for which column this uniqueness exception was raised. ? i don't want to use .valid? method of rails as it is going to run validation again.

Upvotes: 0

Views: 1063

Answers (1)

Schwern
Schwern

Reputation: 165218

Normally you'd use the non-exception versions like save or create instead of save! and create!. Then check which columns are invalid on the model's validation errors.

user = User.create(name: "Duplicate")
if user.model.errors.include?(:name)
  ...
end

However, the ActiveRecord::RecordNotUnique exception comes from the database. There's no validation error.

You can fix this by adding your own uniqueness validation to the model which runs before Rails tries to save the model.

class User < ApplicationRecord
  validates :name, uniqueness: true
end

Now you'll get a validation error.

However, this requires a query to check uniqueness. That can affect performance, and also lead to race conditions. Imagine you try to create two Users with the same name at the same time. They both check if the name is taken, they both see that it is not, and they both try to insert. One succeeds, one fails with an ActiveRecord::RecordNotUnique.

Instead, use the excellent database_validations gem which turns database errors into validation errors. This is safer, faster, and you only need one way to check for validation errors.

class User < ApplicationRecord
  validates :name, db_uniqueness: true
end

Upvotes: 2

Related Questions