What’s the difference between db:test:clone, db:test:clone_structure, db:test:load, and db:test:prepare?

Very good question. Had me stumped so I dove into the rails source and pulled up database.rake. Now it’s more clear:

  • db:test:clone is just a combination of db:schema:dump and db:test:load:

    task :clone => %w(db:schema:dump db:test:load)
    
  • db:test:clone_structure uses the {rails_env}_structure.sql file:

    task :clone_structure => [ 'db:structure:dump', 'db:test:purge' ] do
      # skipped some code, here's what happens for MySQL:
      ActiveRecord::Base.establish_connection(:test)
      # ...
      IO.readlines("#{Rails.root}/db/#{Rails.env}_structure.sql").join.split("\n\n").each do |table|
        ActiveRecord::Base.connection.execute(table)
      end
    end
    
  • db:test:load is the same as db:schema:load, but invokes it on the test database:

    task :load => 'db:test:purge' do
      ActiveRecord::Base.establish_connection(ActiveRecord::Base.configurations['test'])
      # ...
      db_namespace['schema:load'].invoke
    end
    
  • db:test:prepare alerts you if any migrations are pending, and if not, either runs db:test:clone_structure (using the {rails_env}_structure.sql file) or db:test:load (using the schema.rb file), depending on the schema format (this is a little confusing to me, maybe someone else can expand on it):

    task :prepare => 'db:abort_if_pending_migrations' do
      # ...
      db_namespace[{ :sql  => 'test:clone_structure', :ruby => 'test:load' }[ActiveRecord::Base.schema_format]].invoke
    end
    

Hope this clears it up! Again, going through the database.rake file is easy and will clear up any other questions you might have. That link goes to the line that is the beginning of the :test namespace.

Leave a Comment