6

I'm trying to add test fixtures to a rails (v 3.1.3) app that uses multiple databases. The fixture should be applied only to the applications own test sqlite database:

test:
  adapter: sqlite3
  database: db/test.sqlite3
  pool: 5
  timeout: 5000

The 2 other databases are mysql and also have test instances called %dbname%_test and are already filled with test data.

After I added the fixtures all my test fail with "ActiveRecord::StatementInvalid: Mysql::Error: Unknown column" errors as rails is trying to apply the fixture to one of the mysql databases.

Is there a way to specify which database a fixture is made for?

tee
  • 4,149
  • 1
  • 32
  • 44
Abraxas
  • 73
  • 6

2 Answers2

4

Fixtures-init code (in activerecord-3.2.6/lib/active_record/fixtures.rb) has a bug: in the "initialize" method, in the "else" on line 544, @connection needs to be initialized to @model_class.connection. (Without that, @connection is simply "connection" which points to the wrong DB.)

tee
  • 4,149
  • 1
  • 32
  • 44
aqn
  • 2,542
  • 1
  • 16
  • 12
  • Thanks for this -- is there a corresponding bug in the Ruby on Rails tracker (i.e., do they know about this)? – jgoldschrafe Apr 10 '13 at 13:47
  • jgoldschrafe: AFAICT, looks like it has been fixed in the current ActiveRecord, line 519: @connection = ( model_class.respond_to?(:connection) ? model_class.connection : connection ) – aqn May 15 '13 at 19:59
  • @aqn: I'm still seeing `SQLite3::SQLException: no such table:` errors, actually. Not sure if it's still broken or if I'm doing something wrong. – user1618143 Jan 23 '14 at 16:25
  • I'm currently able to load fixtures into different databases using the method described in @tee's answer (activerecord 4.1.4) – sixty4bit Feb 08 '16 at 17:47
2

In database.yml, add a connection for each of the other databases for each environment:

other_one_test:
  adapter: mysql
  # ...

other_two_test:
  # ...

other_one_development:
  # ...

other_two_development:
  # ...

In your models that use the other databases, connect to them using

establish_connection("other_one_test")

You'll probably want to create a Base class model for each different database connection and use that for all models connecting to that database:

class OtherOneBase < ActiveRecord::Base
  establish_connection "other_one_#{Rails.env}"
end

class SomeModel < OtherOneBase
end

If you set up your models correctly, your fixtures will use the correct database.

tee
  • 4,149
  • 1
  • 32
  • 44
  • 1
    That's exactly the way my databases/models were set up, and really the only practical way to do it in rails but it just didn't work. In the end I've got rid of one of the mysql db's and switched to using the applications API (I've previously opted to use the db directly for better perfomance) and replaced fixtures with factory's. – Abraxas Dec 06 '11 at 21:58
  • I'm currently able to load fixtures into different databases using this method (activerecord 4.1.4) – sixty4bit Feb 08 '16 at 17:47