ale
ale

Reputation: 11824

Correct way of prevent duplicate records in Rails

In my model I have this:

validates :name, :presence => true, :uniqueness => true

In my controller I have:

...
if @location.save
    format.html { redirect_to @location, :notice => 'Location was successfully created.' }
    format.json { render :json => @location, :status => :created }
...

which successfully creates a record if there isn't already a record with this name in the table. I think it's good practice to check before inserting a possibly duplicate record instead of relying on the DB constraints?

I guess I should add something to the controller to check? What's the correct way to do this?

Many thanks.

Upvotes: 6

Views: 18466

Answers (5)

user3402754
user3402754

Reputation: 3085

Your validation is correct. Just like all the other answers above, however assuming you want to validate multiple fields for example assuming you have a wishlist, that takes the user_id and the item_id, you need each item to be added only once by a user, for this kind of scenario add this type of validation to your model

Class class_name < ActiveRecord::Base
  validates_uniqueness_of   :item_id, scope: :user_id
end

Upvotes: 4

Teddy
Teddy

Reputation: 18572

Add a unique index in your database. That way, if something slips through the model validations (rare, but technically possible), the query to save to the database will fail.

Upvotes: 9

jvnill
jvnill

Reputation: 29599

You have the correct way of validating uniqueness in Rails and that is through validations. You don't need to check this in the controller because that's what the validation does for you.

Remember that adding a uniqueness validation doesn't guarantee that you'll have a unique record in the db. This is explained nicely in the validates_uniqueness_of documentation in the api.

Upvotes: 2

MrTheWalrus
MrTheWalrus

Reputation: 9700

Validations are done by Rails before the record would hit the database. If the record fails a validation, it won't save, and .save will return false, which will cause the else clause of your controller to execute. That clause usually rerenders the page that was submitted, with the errors displayed so they can be corrected.

Assuming that your controller is built like that, you don't need to do anything else. You should, naturally, make sure that any database constraints are mirrored in your validations, otherwise a record might pass validations but produce an error from violating a constraint when it was saved.

Upvotes: 8

Salil
Salil

Reputation: 47472

You don't need to do anything in controller.

The correct way to prevent duplicate records in Rails is used 
validation in model which you did correctly.

Upvotes: 6

Related Questions