0
0

More than 1 year has passed since last update.

Active Record の transaction を雰囲気で書いて rollback されてなかったということがないようにしたいメモ記事

Last updated at Posted at 2022-11-28

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
0
0
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0