Reputation: 266940
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
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
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