Search code examples
ruby-on-railsrails-activerecorddatabase-cleaner

rails ActiveRecord transactional Integrity / Data not committing mid scenario spec?


I know i'm mis-understanding how ActiveRecord maintains integrity/works: hoping someone can clarify for me explaining why the following is not working?

We have an abnormal situation: our rails app calls a compiled binary that accesses (and creates a new table rows, it does not update existing) in a shared database. We therefore run config.use_transactional_fixtures = false in rails_helper (other wise we get savepoint errors). The data needs to commit within the scenario so this legacy app can access the data in the database during the test.

During a test we are setting up data via eval(rubyexpression) (see below for full code)

  "provider = Provider.create({:provider_reseller_phone_number => '0200000000', :provider_registered_business_name => 'ProviderReseller', :provider_name => 'providerwithzero'})"

NOTE:

  • i know we should be using factorygirl for this, thats a different long story
  • there is no additional provider model code e.g. callbacks, hooks are anything

using debugger to pause the test (line 22), the data is not saved to the database, but it is there once the rspec completes.

We cannot figure out why!? surely data is committed after each transaction e.g. eval?

appreciate any guidance / learnings?

we've tried

spec_test_eval.rb

require 'rails_helper'

describe 'trying to test using rails populated data for external process' do

  it 'populates provider and tests external process' do
      initial_data = "provider = Provider.create({:provider_reseller_phone_number => '0200000000', :provider_registered_business_name => 'ProviderReseller', :provider_name => 'providerwithzero'})"
    eval(initial_data)
    debugger
    expect Provider.all.count.eql?(1)
    # using mysql to check providers table its empty
    exec_path_str = "#{EXTERNALPROCESS} 1 1"
    stdop_content = `#{exec_path_str}`
  end
end

test.log output

     ActiveRecord::SchemaMigration Load (0.2ms)  SELECT `schema_migrations`.* FROM `schema_migrations`
       (0.1ms)  BEGIN
       (0.1ms)  SAVEPOINT active_record_1
      SQL (0.2ms)  INSERT INTO `providers` (`created_at`, `provider_name`, `provider_registered_business_name`, `provider_reseller_phone_number`, `updated_at`) VALUES ('2014-12-27 03:33:21', 'providerwithzero', 'ProviderReseller', '0200000000', '2014-12-27 03:33:21')
       (0.1ms)  RELEASE SAVEPOINT active_record_1
       (0.2ms)  SELECT COUNT(*) FROM `providers`
       (0.4ms)  ROLLBACK

Solution

  • So it seems that its the DatabaseCleaner gem thats causing this behaviour.

    Having understood truncation, transaction etc. differences (database cleaner strategies we had transaction enabled which forces the surrounding transaction and rollback. But using DatabaseCleaner.strategy = :truncation) allows each ActiveRecord action to commit to the database. At a speed cost.

    Given this does slow up the tests and we only need on some special tests, now searching solutions for different strategies based on flags/attributes.