Skip to content

Commit a164b66

Browse files
patnnishimura
andauthored
truncate_option to allow CASCADE mode alongside the default RESTRICT (#118)
* Add option to specify CASCADE and RESTRICT for Truncation strategy * Add tests for truncate_option --------- Co-authored-by: Naoko Nishimura <naoko.nishimura1018@gmail.com>
1 parent d34716a commit a164b66

3 files changed

Lines changed: 34 additions & 7 deletions

File tree

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,8 @@ DatabaseCleaner[:active_record].strategy = DatabaseCleaner::ActiveRecord::Deleti
6363

6464
* `:reset_ids` - Only valid for deletion strategy, when set to `true` resets ids to 1 after each table is cleaned.
6565

66+
* `:truncate_option` - Only valid for PostgreSQL. Acceptable values are `:restrict` and `:cascade`. Default is `:restrict`
67+
6668
## Adapter configuration options
6769

6870
`#db` defaults to the default ActiveRecord database, but can be specified manually in a few ways:

lib/database_cleaner/active_record/truncation.rb

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
require "delegate"
2+
require 'database_cleaner/active_record/base'
23

34
module DatabaseCleaner
45
module ActiveRecord
56
class Truncation < Base
67
def initialize(opts={})
7-
if !opts.empty? && !(opts.keys - [:only, :except, :pre_count, :cache_tables, :reset_ids]).empty?
8-
raise ArgumentError, "The only valid options are :only, :except, :pre_count, :reset_ids, and :cache_tables. You specified #{opts.keys.join(',')}."
8+
if !opts.empty? && !(opts.keys - [:only, :except, :pre_count, :cache_tables, :reset_ids, :truncate_option]).empty?
9+
raise ArgumentError, "The only valid options are :only, :except, :pre_count, :reset_ids, :cache_tables and :truncate_option. You specified #{opts.keys.join(',')}."
910
end
1011

1112
@only = Array(opts[:only]).dup
1213
@except = Array(opts[:except]).dup
1314

1415
@reset_ids = opts[:reset_ids]
1516
@pre_count = opts[:pre_count]
17+
@truncate_option = opts[:truncate_option] || :restrict
1618
@cache_tables = opts.has_key?(:cache_tables) ? !!opts[:cache_tables] : true
1719
end
1820

@@ -21,7 +23,7 @@ def clean
2123
if pre_count? && connection.respond_to?(:pre_count_truncate_tables)
2224
connection.pre_count_truncate_tables(tables_to_clean(connection))
2325
else
24-
connection.truncate_tables(tables_to_clean(connection))
26+
connection.truncate_tables(tables_to_clean(connection), { truncate_option: @truncate_option })
2527
end
2628
end
2729
end
@@ -101,7 +103,7 @@ def truncate_table(table_name)
101103
execute("DELETE FROM #{quote_table_name(table_name)}")
102104
end
103105

104-
def truncate_tables(tables)
106+
def truncate_tables(tables, opts)
105107
tables.each { |t| truncate_table(t) }
106108
end
107109
end
@@ -151,7 +153,7 @@ def truncate_table(table_name)
151153
end
152154
end
153155

154-
def truncate_tables(tables)
156+
def truncate_tables(tables, opts)
155157
tables.each { |t| truncate_table(t) }
156158
end
157159

@@ -192,9 +194,10 @@ def database_tables
192194
tables_with_schema
193195
end
194196

195-
def truncate_tables(table_names)
197+
def truncate_tables(table_names, opts)
196198
return if table_names.nil? || table_names.empty?
197-
execute("TRUNCATE TABLE #{table_names.map{|name| quote_table_name(name)}.join(', ')} RESTART IDENTITY RESTRICT;")
199+
200+
execute("TRUNCATE TABLE #{table_names.map{|name| quote_table_name(name)}.join(', ')} RESTART IDENTITY #{opts[:truncate_option]};")
198201
end
199202

200203
def pre_count_truncate_tables(tables)

spec/database_cleaner/active_record/truncation_spec.rb

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,28 @@
100100
end
101101
end
102102

103+
describe "with truncate_option set to cascade" do
104+
subject(:strategy) { described_class.new(truncate_option: :cascade) }
105+
106+
it "specifies cascade when truncating" do
107+
User.create!({name: 1})
108+
109+
expect(strategy.send(:connection)).to receive(:truncate_tables).with(['users', 'agents'], {truncate_option: :cascade})
110+
strategy.clean
111+
end
112+
end
113+
114+
describe "with no truncate_option set" do
115+
subject(:strategy) { described_class.new }
116+
117+
it "specifies restrict when truncating" do
118+
User.create!
119+
120+
expect(strategy.send(:connection)).to receive(:truncate_tables).with(['users', 'agents'], {truncate_option: :restrict})
121+
strategy.clean
122+
end
123+
end
124+
103125
context 'when :cache_tables is set to true' do
104126
subject(:strategy) { described_class.new(cache_tables: true) }
105127

0 commit comments

Comments
 (0)