问题
I'm having a few issues with duplicate records in my database which I believe are being caused by people clicking submit multiple times. I am using Rails 3.
Return the duplicated object rather than false
I would like to be able to prevent duplicates from being added to my database, but would prefer it if when saving a duplicate, the object that was duplicated was returned, rather than false. The reason being that if someone clicks submit several times, I would like them to be taken to a page showing them the item they submitted first, rather than to an error page.
Definition of a duplicate
I'm defining a duplicate as an item in which all the fields except the ID are the same, and created_at > Time.now - 1.minute
No JavaScript
I would prefer to do this serverside rather than just disabling the button in JavaScript since I don't think database integrity is a client side job. Also, it feels like it should be done in the model, rather than the controller. I'm running multiple passengers, so any solution should ideally avoid concurrency issues as much as possible. A few edge case duplications would not break the site though.
Thanks.
回答1:
ActiveRecord solution
ActiveRecord has a concept of dynamic finders:
User.find_or_create_by_first_name_and_last_name_and_age_and_whatelse(first_name,
last_name,
age,
whatelse)
Not sure how to place your "last minute" logic here.
Alternate solution
I would do roughly this:
On user click insert new record. Memorize its id.
Check if similar records were already posted in the last minute.
If there was one (or several), delete your new record, fetch and return the oldest.
If there was no existing record, return new one.
It's better than "first check, then insert", because it avoids race conditions.
It will create some gaps in id sequence, though. Some people don't like that. :-)
来源:https://stackoverflow.com/questions/8943626/prevent-duplicates-from-saving-in-active-record-and-return-the-object-that-was