#はじめに
Railsで複数レコードを作成、更新する際にActiveRecord::Base.transactionをどのように用いるかを調べた際のメモです。
主に以下を参考にさせていただきました。
https://qiita.com/aba0312/items/8b29cafe6b505b6a7a4f
https://www.youtube.com/watch?v=jFBvEQhApKQ
#例
例えば、ユーザーのバルクインサートを行う際に全てのインサートが成功しなければロールバックするという想定をします。
User.rb
class User < ApplicationRecord
def self.bulk_create(users)
all_valid = true
transaction(join_table: false, requires_new: true) do
users.each do |user|
# 何らかの処理
all_valid &= user.save
end
unless all_valid
raise ActiveRecord::Rollback
end
end
all_valid
end
end
transactionの引数である、join_tableやrequires_newはこちらを参考にしました。
https://qiita.com/jnchito/items/930575c18679a5dbe1a0
この書き方をすることによって、システムエラー(プログラムのバグにより起こるエラー)が起きればその時点でロールバックがされますし、業務エラー(ユーザーの操作によるエラー)が起きればRollbacを明示的にするようにしています。
users_controller.rb
class UsersController < ApplicationContoller
def create
if User.bulk_create(@users)
redirect_to :index
else
# エラー通知
render :new
end
end
end
#おわりに
おかしい部分があるかもしれません。ご指摘あればよろしくお願い致します。