DatabaseCleaner/database_cleaner-active_record

Rails 6 with database_cleaner-active_record ~>1.8 wipe all tables even with except

bf39l opened this issue · 5 comments

bf39l commented

database: postgresql 11
Rails 6
rspc-rails ~>4.0
database_cleaner-active_record ~>1.8
spec_helper.rb

  require 'database_cleaner-active_record'
  DatabaseCleaner[:active_record, connection: :test]

  tables_to_be_excluded = %w[public.spatial_ref_sys public.foo]

  config.before(:suite) do
    load "#{Rails.root}/db/seeds.rb"
    DatabaseCleaner.strategy = :truncation, { except: tables_to_be_excluded }
    DatabaseCleaner.clean_with(:truncation, { except: tables_to_be_excluded })
    puts 'Cleaned up database and feed seeds'
    # this step will wipe all data in all tables
  end
  config.before(:each) do
    DatabaseCleaner.start
  end
  config.after(:each) do
    DatabaseCleaner.clean
  end
bf39l commented

I updated gem to database_cleaner, = 1.7.0 with following rspec config

  config.before(:suite) do
    DatabaseCleaner.strategy = :truncation, { except: tables_to_be_excluded }
    DatabaseCleaner.clean_with(:truncation, { except: tables_to_be_excluded })
    load "#{Rails.root}/db/seeds.rb"
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :truncation, { except: tables_to_be_excluded }
    DatabaseCleaner.clean_with(:truncation, { except: tables_to_be_excluded })
  end

And confirmed database_cleaner just clean up required tables.
UPDATE: also tested with gem database_cleaner 1.8.5, it cleaned up required tables

I've just spent an afternoon to debug similar problem and I've found out that if you are using postgres then tables are truncated with CASCADE option which truncates not only tables that are not in except option but if any of these tables reference table that is truncated, it will be silently truncated as well despite being in except.

bf39l commented

Right, that kinda make sense, just wondering if I have two tables like below
Table "students": id (pk), name
Table "classrooms": id (pk), student_id (fk =>id from students)
When I clean tuples in classrooms, will it clean up students?

It's rather other way around. If you exclude classrooms from being truncated and try to truncate all other tables, so in this case only students table, students table cannot be removed separately from classrooms as classrooms references student_id. So with CASCADE option classrooms will be silently truncated as well despite excluding it from being truncated.

Postgres TRUNCATE command can be run with RESTRICT option which does the opposite to CASCADE, if reference like that is found truncation will fail with pretty self-explanatory error message. I've created another issue to maybe add an option to use RESTRICT instead of CASCADE #57

bf39l commented

Understood now. I will close this issue now and head back to that project to give a try. Thank you @bsuchodolski .