I’ve got a Users table with an Email column in my database. I’ve also created a UNIQUE index on the Email column to prevent two users from registering the same email address (note: please don’t suggest that I use validates_uniqueness_of since this is what I’m trying to avoid).
When I run run my RSpec test to make sure that a duplicate record cannot be inserted, I see the following error:
Failures:
1) User should not allow duplicate email addresses
Failure/Error: user2.save.should_not be_true
ActiveRecord::RecordNotUnique:
SQLite3::ConstraintException: column email is not unique: INSERT INTO "users" ("email", ... ) VALUES ( ... )
# ./spec/models/user_spec.rb:26
This is good because it means that my UNIQUE index is indeed working. The question is, how can I handle this exception? I’d like to be able to catch it, then add a sensible message to the model’s errors collection.
I’ve tried – unsuccessfully – using rescue_from in the controller as follows:
rescue_from 'ActiveRecord::RecordNotUnique' do |ex|
raise 'Email must be unique'
end
The Rails API docs don’t appear to suggest how to override the save() method in order to add a begin/rescue block, so my question is this: How can I handle the ActiveRecord::RecordNotUnique exception that is being thrown during save() then mark the model as invalid and add a sensible error message to the model’s errors collection?
You can overload any action in your models and just call
superto execute the inherited method definitionThe Rails API prolly doesn’t mention it because its an feature of Ruby, not just Rails.