0

I have a Rails 4 application that uses two MySQL databases (primary, secondary). Both databases are configured for development, production and test environments in the database.yml file:

development:
  ...
  database: primary
  ...

production:
  ...
  database: primary
  ...
test:
  ...
  database: primary
  ...

secondary_development:
  ...
  database: secondary
  ...

secondary_production:
  ...
  database: secondary
  ...

secondary_test:
  ...
  database: secondary
  ...

For now I only have one model that is stored in the secondary db. Below is the migration code that creates a table for this model:

class CreateTags < ActiveRecord::Migration
 ActiveRecord::Base.establish_connection "secondary_#{Rails.env}"
 def change
   create_table :tags do |t|
     t.string :name
     t.integer :account_id
     t.timestamps
   end
 end
end

When I run rake db:migrate, the table is correctly created in the secondary database. But when I run rake db:migrate a second time, it shows me an error table already exists, which I think related to the fact that rake task adds migration version to versions table of primary database. I am ignoring this for now.

But, when I run some unit test using rake test TEST=test/path_to_test_file.rb, it shows me an error saying Tags table does not exist in the secondary DB. I've checked the logs and found that Tags table is created, BUT in PRIMARY database which is wrong.

So, in short, how to change the migration code to make sure that Tags table will always be created in the secondary DB?

I have tried:

But it is not working for me :(

UPDATE 1: Based on @User089247 suggestion, I have tried to run RAILS_ENV=test rake db:create and RAILS_ENV=test rake db:migrate. It says that my primary database is already created which is true, but it says nothing about my secondary databse because secondary DB has separate configuraion secondary_test. Based on my understanding, it should be possible to create custom rake task (or override existing one) but then this taks should be used by rake test. Is it possible ? Or am I missing somethings ?

Community
  • 1
  • 1
  • Did you also run: `$ RAILS_ENV=test rake db:create` and then `$ RAILS_ENV=test rake db:migrate`? – Surya Oct 27 '14 at 11:19
  • I have not tried that, but based on my understanding, it should help me to resolve issue with running rake db:migrate. This issue is not critical for me right now, so the focus is on the issue with rake test – Nikolay Melezhik Oct 27 '14 at 11:40
  • https://gist.github.com/rafaelchiti/5575309 This kind of looks like what you are trying to do, also you database.yml is specifying the secondary database over every environment, which seems odd to me. – jfornoff Oct 27 '14 at 14:55

1 Answers1

0

What you want to do here is specify the usage of the secondary database on the model, not just in the migration:

class Tag < ActiveRecord::Base
  establish_connection "secondary_#{Rails.env}" 
end

This blog post has some helpful additional info if you are going to be using the secondary database for multiple models: http://pragdave.me/blog/2006/01/03/sharing-external-activerecord-connections/

eirik909
  • 1
  • 2
  • Thanks for your reply, but establish_connection is already added to Tag model and Tag entity can be saved,retrieved and deleted in the Rails application correctly. The problem I am facing is related to unit testing part of Rails. – Nikolay Melezhik Oct 27 '14 at 18:01
  • My apologies. I misunderstood your original question. It looks like the gist linked to in the final comment above will put you on the right track. This is the source code that you will need to override/customize in order to get the behavior you want: https://github.com/rails/rails/blob/master/activerecord/lib/active_record/railties/databases.rake – eirik909 Oct 31 '14 at 23:47