ApplicationRecord.transaction do を理解する
大きく分けて2種類書き方がある
rollbackされる
def do_rollback
ApplicationRecord.transaction do
Member.create!(email: 'duplicate@gmail.com', password: 'a')
end # ← end で block を閉じた場合 rollback 処理が行われます。
rescue ActiveRecord::RecordInvalid
p "エラー"
end
end
rollbackされない
def do_rollback
ApplicationRecord.transaction do
Member.create!(email: 'duplicate@gmail.com', password: 'a')
# end を入れない場合、rollback が行われません。
rescue ActiveRecord::RecordInvalid
p "エラー"
end
end
詳細な理解はこちらを参考に
https://qiita.com/ytnk531/items/a0db31ee4311425a3933
手元でテストできるコード
パスワードの長さが原因で rollback されます
手元で実行して理解しておきましょう
rollbackテスト
# ロールバックされない処理
def dont_rollback
ApplicationRecord.transaction do
Member.create!(email: 'duplicate@gmail.com', password: 'asadjfi9_$asdf')
Member.create!(email: 'duplicate@gmail.com', password: 'a')
rescue ActiveRecord::RecordInvalid
p "エラー"
end
end
def test_dont_rollback
before = Member.last.id
dont_rollback
after = Member.last.id
p "#{before} : #{Member.last.id} (#{before == after})"
end
# ロールバックされる処理
def do_rollback
ApplicationRecord.transaction do
Member.create!(email: 'duplicate@gmail.com', password: 'asadjfi9_$asdf')
Member.create!(email: 'duplicate@gmail.com', password: 'a')
end
rescue ActiveRecord::RecordInvalid
p "エラー"
end
end
def test_do_rollback
before = Member.last.id
do_rollback
after = Member.last.id
p "#{before} : #{Member.last.id} (#{before == after})"
end
test_do_rollback
test_dont_rollback