如何识别 Rails 6 批量插入错误
Posted
技术标签:
【中文标题】如何识别 Rails 6 批量插入错误【英文标题】:How to identify Rails 6 bulk insert error 【发布时间】:2022-01-07 18:39:36 【问题描述】:我建立了以下关系:
user has_many quizzes
quiz belongs_to user
quiz has_many questions
question belongs_to quiz
应用程序设置为使用 PostgreSQL。我正在尝试使用insert_all!
方法批量插入一堆记录
begin
quiz = user.quizzes.create!(title: title, slug: slug)
quiz_questions = params[:quiz][:questions].map! do |q|
# creating an attribute hash here (code removed for conciseness of question)
end
result = quiz.questions.insert_all!(quiz_questions)
这引发了一个被我的“catch all”块捕获的错误
rescue ActiveRecord::ActiveRecordError
render json: message: ['Something went wrong'] , status: 500
正在运行的服务器控制台打印了这条消息:
TRANSACTION (0.9ms) BEGIN
↳ app/controllers/quizzes_controller.rb:14:in `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", "a quiz"], ["user_id", 1], ["slug", "a-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 `create'
TRANSACTION (1.6ms) COMMIT
↳ 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 ('what is name', 'str', 'char', 'num', 'bool', 5, 'A', 1), ('die', 'yes', 'no', 'ok', 'what', 5, 'B', 1) RETURNING "id"
↳ (eval):6:in `block in insert_all!'
Completed 500 Internal Server Error in 153ms (Views: 0.2ms | ActiveRecord: 38.1ms | Allocations: 49609)
所以我认为我没有正确调用insert_all!
,因为服务器只是在没有BEGIN
和COMMIT
书挡的情况下进行插入。另外,我想知道 catch all 块正在抛出和捕获哪个错误。 insert_all!
的正确做法是什么?
【问题讨论】:
【参考方案1】:您可以将批量插入包装到事务中
def bulk_insert
ActiveRecord::Base.transaction do
quiz = user.quizzes.create!(title: title, slug: slug)
quiz_questions = params[:quiz][:questions].map! do |q|
# creating an attribute hash here
# ...
# note that you could validate attribute manually
raise ActiveRecord::Rollback if q.description.blank?
end
result = quiz.questions.insert_all!(quiz_questions)
end
rescue ActiveRecord::Rollback => e
puts e
end
【讨论】:
我在这里发布后立即尝试了这个。 activerecord::Rollback 未被救援块捕获。 @kchak 交易成功了吗?我的意思是它是否回滚了quiz
和quiz_questions
(出现问题时)?除此之外,您可以尝试rescue StandardError
来捕获错误。
谢谢@Lam-Phan 我没有用 insert_all 试过这个!我认为当个别行无效时需要额外的逻辑。一旦我有时间做这件事,我会通知你的。以上是关于如何识别 Rails 6 批量插入错误的主要内容,如果未能解决你的问题,请参考以下文章