Using Rails Migration on different database than standard “production” or “development”

前端 未结 20 1328
借酒劲吻你
借酒劲吻你 2020-11-29 18:18

I have a rails project running that defines the standard production:, :development and :test DB-connections in config/database.yml

In addition I have a quiz_developm

相关标签:
20条回答
  • 2020-11-29 19:12

    For Rails 3.2, this is what we did, works with migrating up and down:

    class CreateYourTable < ActiveRecord::Migration
    
      def connection
        @connection ||= ActiveRecord::Base.connection
      end
    
      def with_proper_connection
        @connection = YourTable.connection
        yield
        @connection = ActiveRecord::Base.connection
      end
    
    
      def up
        with_proper_connection do
          create_table :your_table do |t|
          end
        end
      end
    
      def down
        with_proper_connection do
          drop_table :your_table
        end
      end
    
    end
    
    0 讨论(0)
  • 2020-11-29 19:12

    In rails 3.2, adding a connection method to your migration does NOT work. So all of the answers like

    def connection
     @connection ||= ActiveRecord::Base.establish_connection
    end
    

    simply won't work (can't down, doesn't work with change, connection lost, etc.) The reason for this is that the ActiveRecord::Migration and Migrator class have connections hard-coded to ActiveRecord::Base all over the place.

    Fortunately this post pointed me to this ticket which has a good solution, namely overriding the actual rake task.

    I ended up using a slightly different rake task so that I could be specific about the migrations I run on the different database (we were trying to support multiple db versions):

    Here's my lib/task/database.rake

    # Augment the main migration to migrate your engine, too.
    task 'db:migrate', 'nine_four:db:migrate'
    
    namespace :nine_four do
        namespace :db do
            desc 'Migrates the 9.4 database'
            task :migrate => :environment do
                with_engine_connection do
                    ActiveRecord::Migrator.migrate("#{File.dirname(__FILE__)}/../../nine_four/migrate", ENV['VERSION'].try(:to_i))
                end
            end
        end
    end
    
    # Hack to temporarily connect AR::Base to your engine.
    def with_engine_connection
        original = ActiveRecord::Base.remove_connection
        ActiveRecord::Base.establish_connection("#{ Rails.env }_nine_four")
        yield
    ensure
        ActiveRecord::Base.establish_connection(original)
    end
    

    This allows us to put migrations specific to one database in their own subdirectory (nine_four/migrations instead of db/migrations). It also gives each database total isolation in terms of their schema and migration versions. The only downside is having two rake tasks to run (db:migrate and nine_four:db:migrate).

    0 讨论(0)
提交回复
热议问题