Comment puis-je faire de ruby on rails gérer la duplication de consigner les erreurs de MySQL
J'ai un index unique sur plusieurs champs de ma base de données. Donc, si vous essayez d'appeler la méthode save sur une copie de l'enregistrement, il soulève ActiveRecord::StatementInvalid et montre l'erreur mysql. Est-il un moyen de gérer cela dans les rails, soit par la création de la contrainte unique ou sinon avoir un retour pertinent message d'erreur lorsque cela se produit?
heres la trace:
ActiveRecord::StatementInvalid: Mysql::Error: Duplicate entry '2010-12-09-2-0-1-1' for key 2: INSERT INTO `entries` (`rejected_at`, `created_at`, `comments`, `overtime`, `submitted_at`, `updated_at`, `time`, `approved`, `day`, `user_id`, `approved_at`, `job_id`, `submitted`, `rejected`) VALUES(NULL, '2010-12-09 21:50:46', NULL, 0, NULL, '2010-12-09 21:50:46', 2.0, NULL, '2010-12-09', 1, NULL, 1, NULL, NULL)
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:219:in `log'
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb:319:in `execute'
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:259:in `insert_sql'
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/connection_adapters/mysql_adapter.rb:329:in `insert_sql'
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:44:in `insert_without_query_dirty'
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/query_cache.rb:18:in `insert'
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/base.rb:2901:in `create_without_timestamps'
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/timestamp.rb:53:in `create_without_callbacks'
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/callbacks.rb:266:in `create'
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/base.rb:2867:in `create_or_update_without_callbacks'
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/callbacks.rb:250:in `create_or_update'
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/base.rb:2538:in `save_without_validation'
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/validations.rb:1078:in `save_without_dirty'
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/dirty.rb:79:in `save_without_transactions'
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/transactions.rb:229:in `send'
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/transactions.rb:229:in `with_transaction_returning_status'
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb:136:in `transaction'
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/transactions.rb:182:in `transaction'
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/transactions.rb:228:in `with_transaction_returning_status'
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/transactions.rb:196:in `save'
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/transactions.rb:208:in `rollback_active_record_state!'
from /home/cmatthews/src/cannon/vendor/rails/activerecord/lib/active_record/transactions.rb:196:in `save'
OriginalL'auteur loosecannon | 2010-12-09
Vous devez vous connecter pour publier un commentaire.
Vous pouvez ajouter une contrainte d'unicité à votre modèle, de sorte que le dossier de retour avec des erreurs et n'est pas valide.
Par exemple (Rails 2):
ou (Rails 3)
Cela devrait le résultat suivant:
Hey, j'ai mis à jour le post avec la réponse de plusieurs attributs.
Tandis que qui couvre la plupart des cas d'utilisation, il est et a toujours été une condition de concurrence dans validates_uniqueness_of - il ne marche pas arrêter les entrées en double à cause de la façon dont il fonctionne.
C'est exact, Omar. Vous devriez toujours avoir un index unique dans MySQL sur (nom, prénom, âge, e-mail) et il est préférable d'entourer vos mises à jour avec de commencer..de sauvetage..les relevés de fin d'attraper ces cas, si vous pensez que cela pourrait être un problème pour votre application.
OriginalL'auteur Pan Thomakos
Cela fonctionne pour moi sous Rails 3.
Lorsque vous utilisez une configuration maître/esclave-le programme d'installation, vous allez courir dans la dérive des problèmes (et les conditions de course), qui peut être facilement résolu en utilisant cette approche, au lieu d'utiliser des rails unique de validation, ce qui peut vérifier sur l'esclave.
C'est très bien, mais je mettrais ce comportement sur un modèle de méthode avec un nom descriptif.
OriginalL'auteur Michael Voigt
Pouvez-vous modifier la requête pour
Sinon, vous pourriez envisager de
INSERT... ON DUPLICATE KEY UPDATE...
.La
INSERT
Documentation est ici.OriginalL'auteur Riedsio