Blankman
Blankman

Reputation: 266940

Before create callback, how to validate if duplicate record exists and if so return?

Before a record gets created, I want to validate that a similiar record doesn't exist.

When I say similar, I want to compare 3-4 columns to see if they have the same value, if they do, then don't save and report back a validation message.

This only occurs on creation, there might be duplicates during updates etc. but during creation I don't want to allow duplicates.

How can I do this? i.e. which callback is best for this, and how to add to the validation errors collection?

Upvotes: 0

Views: 956

Answers (2)

Prathamesh Sonpatki
Prathamesh Sonpatki

Reputation: 906

You can use first_or_create to chain multiple where clauses and if it is not present create it.

For eg.

 Post.where(author: 'tom').where(subject: 'Rails is awesome').first_or_create!

This will raise exception

More info here, (Assuming you are using Rails 3.2+)

http://guides.rubyonrails.org/v3.2.14/active_record_querying.html#first_or_create

Update

Sorry i misunderstood your question. You don't want to create the object if it already exists. So you can use exists? method which can be called on a model or relation.

For eg.

 post_exists = Post.where(author: 'tom').where(subject: 'Rails is awesome').exists?

If it returns true, we can add error to self

 self.errors.add(:post, "already exists") if post_exists == true

This can be wrapped in a custom validator method which will return false if post_exists is true

def validate_existence_of_post
  post_exists = Post.where(author: 'tom').where(subject: 'Rails is awesome').exists?
  if post_exists == true
    self.errors.add(:post, "already exists")
    return false
  end
  true
end

More info about exists here http://guides.rubyonrails.org/v3.2.14/active_record_querying.html#existence-of-objects

Upvotes: 1

CDub
CDub

Reputation: 13344

I would do something like this:

validate :has_similar_record, :on => :create

...

private

def has_similar_record
  if <Class>.find_by_column1_and_column2_and_column3(column1, column2, column3).present?
    self.errors.add(:base, "record already exists with similar values")
  end
end

Upvotes: 2

Related Questions