Skip to content

Instantly share code, notes, and snippets.

@MITSUBOSHI
Last active March 9, 2021 10:49
Show Gist options
  • Save MITSUBOSHI/8fcb1834473addb213806f54886d6233 to your computer and use it in GitHub Desktop.
Save MITSUBOSHI/8fcb1834473addb213806f54886d6233 to your computer and use it in GitHub Desktop.
To help understanding ActiveRecord::Rollback
# frozen_string_literal: true
require "bundler/inline"
gemfile(true) do
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem "activerecord"
gem "sqlite3"
end
require "active_record"
require "minitest/autorun"
require "logger"
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
ActiveRecord::Base.logger = Logger.new(STDOUT)
ActiveRecord::Schema.define do
create_table :articles, force: true do |t|
t.bigint :category_id
t.string :title, null: false
t.text :content, null: false
end
create_table :categories, force: true do |t|
t.string :name, null: false
end
end
class Article < ActiveRecord::Base
belongs_to :category
end
class Category < ActiveRecord::Base
has_many :articles
end
class TestSingleTransaction < MiniTest::Unit::TestCase
def setup
Article.delete_all
Category.delete_all
end
def test_use_active_record_rollback
returned_value = create_and_rollback_by(ActiveRecord::Rollback)
assert_equal "passed", returned_value
assert_equal 0, Category.all.count
assert_equal 0, Article.all.count
end
def test_use_runtime_error
assert_raises RuntimeError do
create_and_rollback_by(RuntimeError)
end
assert_equal 0, Category.all.count
assert_equal 0, Article.all.count
end
private
def create_and_rollback_by(error)
ActiveRecord::Base.transaction do
category = Category.create!(name: 'test')
Article.create!(category: category, title: 'test', content: 'test')
raise error, 'raised'
end
return 'passed'
end
end
class TestNestedTransaction < MiniTest::Unit::TestCase
def setup
Article.delete_all
Category.delete_all
end
def test_use_active_record_rollback_for_nested_transaction
returned_value = nested_create_and_rollback_by(ActiveRecord::Rollback)
assert_equal "passed", returned_value
assert_equal 1, Category.all.count
assert_equal 1, Article.all.count
end
def test_use_runtime_error_for_nested_transaction
assert_raises RuntimeError do
nested_create_and_rollback_by(RuntimeError)
end
assert_equal 0, Category.all.count
assert_equal 0, Article.all.count
end
private
def nested_create_and_rollback_by(error)
Category.transaction do
category = Category.create!(name: 'test')
Article.transaction do
Article.create!(category: category, title: 'test', content: 'test')
raise error, 'raised'
end
end
return 'passed'
end
end
class TestNestedTransactionWithOption < MiniTest::Unit::TestCase
def setup
Article.delete_all
Category.delete_all
end
def test_use_active_record_rollback_for_nested_transaction
returned_value = nested_create_and_rollback_by(ActiveRecord::Rollback)
assert_equal "passed", returned_value
assert_equal 1, Category.all.count
assert_equal 0, Article.all.count
end
def test_use_runtime_error_for_nested_transaction
assert_raises RuntimeError do
nested_create_and_rollback_by(RuntimeError)
end
assert_equal 0, Category.all.count
assert_equal 0, Article.all.count
end
private
def nested_create_and_rollback_by(error)
Category.transaction(joinable: false, requires_new: true) do
category = Category.create!(name: 'test')
Article.transaction do
Article.create!(category: category, title: 'test', content: 'test')
raise error, 'raised'
end
end
return 'passed'
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment