My Rails 3.1应用程序连接到2个数据库,一个是默认的,另一个是Amazon RDS MYSQL实例。
当前的database.yml包含两个生产数据库连接。需要从第二个数据库中提取的模型只需使用
establish_connection "production_on_amazon"
不幸的是,Heroku会覆盖你的database.yml,而且似乎只包含一个数据库连接。有谁知道如何添加或配置我的第二个?
运行“heroku config”我可以看到列出了2个DB,但似乎无法配置连接到两者。也许以某种方式将我的默认值设置为Heroku上的SHARED_DATABASE_URL数据库,并将备用设置为指向亚马逊的DATABASE_URL ......
答案 0 :(得分:7)
使用以前的响应,但在配置中结合了一些Rails 3的优点并简化了解析......
# config/application.rb
module MyApp
class Application < Rails::Application
... other configs
config.secondary_database_url = ENV['SECONDARY_DB_URL']
end
end
我们可能希望在开发/测试中覆盖它
# config/environments/development.rb
module MyApp
class Application < Rails::Application
... other configs
config.secondary_database_url = 'SOME_CONNECTION_STRING'
end
end
现在要设置这个类,我们的模型将继承自......
# 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
答案 1 :(得分:2)
Heroku将始终将您的应用程序连接到他们为您创建的生产数据库。如果要进行其他连接,则需要手动在代码中执行此操作,并创建一个ENV var,代码可以将其用作连接字符串。
database.yml的生产部分中的任何内容都由Heroku分箱并替换。
答案 2 :(得分:2)
关于尼尔的答案,这是一种方法。不是一个开箱即用的解决方案,但可能会给你一个想法...... /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
因此,您的模型应该只扩展ActiveRecord :: Shard而不是Base