Cómo identificar el error de inserción masiva de Rails 6
Tengo las siguientes relaciones configuradas:
user tiene muchos quizzes
quiz pertenece a usuario
quiz tiene muchas preguntas
pregunta pertenece a quiz
La aplicación está configurada para usar PostgreSQL. Estoy intentando insertar en masa un montón de registros usando el método insert_all!
begin
quiz = user.quizzes.create!(title: title, slug: slug)
quiz_questions = params[:quiz][:questions].map! do |q|
# creando un hash de atributos aquí (código eliminado por concisión de la pregunta)
end
result = quiz.questions.insert_all!(quiz_questions)
Esto lanzó un error que fue capturado por mi bloque de “atrapar todo”:
rescue ActiveRecord::ActiveRecordError
render json: { message: ['Algo salió mal'] }, status: 500
La consola del servidor en ejecución mostró este mensaje:
TRANSACCIÓN (0,9 ms) INICIAR
↳ app/controllers/quizzes_controller.rb:14:in create'
create'
Quiz Create (2.8ms) INSERT INTO "quizzes" ("title", "user_id", "slug", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id" [["title", "un quiz"], ["user_id", 1], ["slug", "un-quizk2DqYk"], ["created_at", "2021-12-01 05: 00: 05.800134 "], ["updated_at", "2021-12-01 05: 00: 05.800134 "]]
↳ app/controllers/quizzes_controller.rb:14:in
TRANSACCIÓN (1.6 ms) COMETER
↳ app/controllers/quizzes_controller.rb:14:in `create'
Question Bulk Insert (0.6ms) INSERT INTO "questions" ("question", "a", "b", "c", "d", "score", "answer", "quiz_id") VALUES ('cuál es el nombre', 'str', 'char', 'num', 'bool', 5, 'A', 1), ('morir', 'sí', 'no', 'ok', 'qué' , 5, 'B', 1) RETORNO "id"
↳ (eval): 6: en el bloque en insert_all!'
Finalizado 500 Error interno del servidor en 153 ms (Vistas: 0,2 ms | ActiveRecord: 38,1 ms | Asignaciones: 49609)
Entonces, creo que no estoy llamando a insert_all!
correctamente porque el servidor simplemente hace una inserción sin los corchetes de BEGIN
y COMMIT
. Además, me gustaría saber qué error está siendo lanzado y atrapado por el bloque de “atrapar todo”. ¿Cuál sería la forma correcta de hacer insert_all!
?
davy.ai
Basándonos en la salida de consola, parece que el método
insert_all!
está funcionando correctamente e insertando los registros en la base de datos. Los mensajesTRANSACTION (0.9ms) BEGIN
,Quiz Create
,TRANSACTION (1.6ms) COMMIT
, yQuestion Bulk Insert
indican que la base de datos está envuelta en una transacción y todas las declaraciones se ejecutan dentro de la misma transacción.Sin embargo, hay un error siendo capturado por el bloque
rescue
, pero no está claro qué tipo de error es. Para ver el mensaje de error real, puede modificar el bloquerescue
de la siguiente manera:Esto capturará cualquier tipo de excepción y devolverá su mensaje en la respuesta.
Suponiendo que no haya otros problemas, la llamada al método
insert_all!
debería funcionar correctamente.