diff --git a/README.md b/README.md index 26a60979..0e15ab68 100644 --- a/README.md +++ b/README.md @@ -61,6 +61,8 @@ DatabaseCleaner[:active_record].strategy = DatabaseCleaner::ActiveRecord::Deleti * `:cache_tables` - When set to `true` the list of tables to truncate or delete from will only be read from the DB once, otherwise it will be read before each cleanup run. Set this to `false` if (1) you create and drop tables in your tests, or (2) you change Postgres schemas (`ActiveRecord::Base.connection.schema_search_path`) in your tests (for example, in a multitenancy setup with each tenant in a different Postgres schema). Defaults to `true`. +* `:reset_ids` - Only valid for deletion strategy, when set to `true` resets ids to 1 after each table is cleaned. + ## Adapter configuration options `#db` defaults to the default ActiveRecord database, but can be specified manually in a few ways: diff --git a/lib/database_cleaner/active_record/deletion.rb b/lib/database_cleaner/active_record/deletion.rb index 72d54155..6b6e41e8 100644 --- a/lib/database_cleaner/active_record/deletion.rb +++ b/lib/database_cleaner/active_record/deletion.rb @@ -19,6 +19,7 @@ def clean def delete_tables(connection, table_names) table_names.each do |table_name| delete_table(connection, table_name) + reset_id_sequence(connection, table_name) if @reset_ids end end @@ -26,6 +27,19 @@ def delete_table connection, table_name connection.execute("DELETE FROM #{connection.quote_table_name(table_name)} WHERE 1=1") end + def reset_id_sequence connection, table_name + case connection.adapter_name + when 'Mysql2' + connection.execute("ALTER TABLE #{table_name} AUTO_INCREMENT = 1;") + when 'SQLite' + connection.execute("delete from sqlite_sequence where name='#{table_name}';") + when 'PostgreSQL' + connection.reset_pk_sequence!(table_name) + else + raise "reset_id option not supported for #{connection.adapter_name}" + end + end + def tables_to_truncate(connection) if information_schema_exists?(connection) @except += connection.database_cleaner_view_cache + migration_storage_names diff --git a/lib/database_cleaner/active_record/truncation.rb b/lib/database_cleaner/active_record/truncation.rb index 2f332948..503e272e 100644 --- a/lib/database_cleaner/active_record/truncation.rb +++ b/lib/database_cleaner/active_record/truncation.rb @@ -5,13 +5,14 @@ module DatabaseCleaner module ActiveRecord class Truncation < Base def initialize(opts={}) - if !opts.empty? && !(opts.keys - [:only, :except, :pre_count, :cache_tables]).empty? - raise ArgumentError, "The only valid options are :only, :except, :pre_count, and :cache_tables. You specified #{opts.keys.join(',')}." + if !opts.empty? && !(opts.keys - [:only, :except, :pre_count, :cache_tables, :reset_ids]).empty? + raise ArgumentError, "The only valid options are :only, :except, :pre_count, :reset_ids, and :cache_tables. You specified #{opts.keys.join(',')}." end @only = Array(opts[:only]).dup @except = Array(opts[:except]).dup + @reset_ids = opts[:reset_ids] @pre_count = opts[:pre_count] @cache_tables = opts.has_key?(:cache_tables) ? !!opts[:cache_tables] : true end diff --git a/spec/database_cleaner/active_record/deletion_spec.rb b/spec/database_cleaner/active_record/deletion_spec.rb index 0b8600d6..79dadbc4 100644 --- a/spec/database_cleaner/active_record/deletion_spec.rb +++ b/spec/database_cleaner/active_record/deletion_spec.rb @@ -42,6 +42,14 @@ expect(User.create.id).to eq 3 end + context "reset_ids option set to true" do + subject(:strategy) { described_class.new(reset_ids: true) } + it "should reset AUTO_INCREMENT index of table" do + strategy.clean + expect(User.create.id).to eq 1 + end + end + it "should delete from all tables except for schema_migrations" do expect { strategy.clean } .to_not change { connection.select_value("select count(*) from schema_migrations;").to_i }