Tengo un índice único en múltiples campos en mi base de datos. Por lo tanto, si intentas guardar en un registro duplicado, activa ActiveRecord :: StatementInvalid y muestra el error mysql. ¿Hay alguna manera de manejar esto dentro de los rieles creando la restricción única o haciendo que devuelva un mensaje de error relevante cuando esto sucede?¿Cómo puedo hacer que Ruby on Rails maneje errores de registro duplicados de MySQL?
heres la traza:
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'
, sé que puedo hacer eso para un campo, pero ¿puedo hacerlo para varios, como puedo tener que verificar para ver si tienen el mismo: correo electrónico, nombre, color favorito y trabajo. Puede haber 5 personas llamadas John, pero solo una puede tener [email protected], naranja, y ser un programador. ¿Tiene sentido? – loosecannon
Oye, actualicé la publicación con la respuesta para múltiples atributos. –
Si bien eso cubre la mayoría de los casos de uso, siempre ha existido una condición de carrera en validates_uniqueness_of - no detiene por completo las entradas duplicadas debido a la forma en que funciona. –