How to use multiple databases for one rails 3.1 app in Heroku?

前端 未结 3 834
忘掉有多难
忘掉有多难 2020-12-15 08:53

My Rails 3.1 application connects to 2 databases, one is the default, the other is an Amazon RDS MYSQL instance.

The current database.yml contains two production dat

相关标签:
3条回答
  • 2020-12-15 09:10

    Working off of the previous responses, but incorporating some Rails 3 advantages with the configuration and simplifying the parsing...

    # config/application.rb
    module MyApp
      class Application < Rails::Application
        ... other configs
    
        config.secondary_database_url = ENV['SECONDARY_DB_URL']
      end
    end
    

    We may want to override this in development / test

    # config/environments/development.rb
    
    module MyApp
      class Application < Rails::Application
        ... other configs
    
        config.secondary_database_url = 'SOME_CONNECTION_STRING'
      end
    end    
    

    Now to setup the class we'll have our models inherit from...

    # lib/active_record/secondary.rb 
    module ActiveRecord
      class Secondary < ActiveRecord::Base
        self.abstract_class = true
    
        # prior to AR 3.2.1
        url = URI.parse( MyApp::Application.config.secondary_database_url )
        establish_connection(
          :adapter  => 'mysql',
          :host     => url.host,
          :username => url.userinfo.split(':')[0],
          :password => url.userinfo.split(':')[1],
          :database => url.path[1..-1],
          :port     => url.port || 3306
        )
    
        # as of AR 3.2.1
        establish_connection(MyApp::Application.config.secondary_database_url)
    
      end
    
      class SecondaryMigration < ActiveRecord::Migration
        def connection
          ActiveRecord::Secondary.connection 
        end
      end
    
    end
    
    0 讨论(0)
  • 2020-12-15 09:13

    Regarding Neil's answer, here is a way to do it. Not an out-of-box solution, but might give you an idea... /lib/active_record_extensions.rb

    module ActiveRecordExtensions
      class Shard < ActiveRecord::Base
        #need to switch to the shard database connection from heroku config 
        primary_database_url = ENV['PRIMARY_DATABASE_URL']
    
        if(!primary_database_url.nil?)
          parsed_connection_string = primary_database_url.split("://")
          adapter = parsed_connection_string[0]
          parsed_connection_string = parsed_connection_string[1].split(":")
          username = parsed_connection_string[0]
          parsed_connection_string = parsed_connection_string[1].split("@")
          password = parsed_connection_string[0]
          parsed_connection_string = parsed_connection_string[1].split("/")  
          host = parsed_connection_string[0]
          database = parsed_connection_string[1]
    
          establish_connection(
            :adapter  => adapter,
            :host     => host,
            :username => username,
            :password => password,
            :database => database,
            :port     => 3306,
            :pool     => 5,
            :timeout  => 5000
          )
        else
          self.establish_connection "shard_#{Rails.env}"
        end
      end
    
      class ShardMigration < ActiveRecord::Migration
        def connection
          ActiveRecord::Shard.connection 
        end
      end
    end
    

    So your model should just extend ActiveRecord::Shard instead of Base

    0 讨论(0)
  • 2020-12-15 09:14

    Heroku will always connect your app to the production DB that they create for you. If you want to make an additional connection you'll need to do this in your code manually, and create a ENV var that the code can use as a connection string.

    Anything in the production segment of database.yml is binned by Heroku and replaced.

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