可以这样做吗?在单个应用程序中,使用SQLite管理许多项目。 我想要的是为我的应用程序管理的每个项目都有一个不同的数据库..所以同一结构化数据库的多个副本,但其中包含不同的数据。我将根据URI上的params选择使用哪个副本。
这是为1.安全性做的..我是这种编程的新手,我不希望它发生在某个原因上工作项目时另一个被破坏了.2。易于备份和旧项目的存档
答案 0 :(得分:39)
默认情况下,Rails不是为多数据库架构而设计的,在大多数情况下,它根本没有意义。 但是,您可以使用不同的数据库和连接。
以下是一些参考资料:
答案 1 :(得分:27)
如果您能够控制和配置每个Rails实例,并且由于它们处于待机状态而您可以负担浪费资源,请省去一些麻烦,只需更改database.yml即可修改每个实例上使用的数据库连接。如果你担心性能,这种方法不会削减它。
对于仅在一个数据库上绑定到单个唯一表的模型,可以在模型中调用establish_connection:
establish_connection "database_name_#{RAILS_ENV}"
如下所述:http://apidock.com/rails/ActiveRecord/Base/establish_connection/class
您将使用来自一个数据库的表和其他不同模型的表使用其他数据库中的表。
如果您有相同的表,在不同的数据库上共用,并由单个模型共享,ActiveRecord将无法帮助您。早在2009年,我就使用Rails 2.3.8对我正在开发的项目提出了这个要求。我有一个每个客户的数据库,我用他们的ID命名数据库。所以我创建了一个方法来更改ApplicationController中的连接:
def change_database database_id = params[:company_id]
return if database_id.blank?
configuration = ActiveRecord::Base.connection.instance_eval { @config }.clone
configuration[:database] = "database_name_#{database_id}_#{RAILS_ENV}"
MultipleDatabaseModel.establish_connection configuration
end
将该方法作为 before_filter 添加到所有控制器:
before_filter :change_database
因此,对于每个控制器的每个动作,当定义和设置params [:company_id]时,它会将数据库更改为正确的数据库。
为了处理迁移我扩展了ActiveRecord :: Migration,其方法是查找所有客户并使用每个ID迭代一个块:
class ActiveRecord::Migration
def self.using_databases *args
configuration = ActiveRecord::Base.connection.instance_eval { @config }
former_database = configuration[:database]
companies = args.blank? ? Company.all : Company.find(args)
companies.each do |company|
configuration[:database] = "database_name_#{company[:id]}_#{RAILS_ENV}"
ActiveRecord::Base.establish_connection configuration
yield self
end
configuration[:database] = former_database
ActiveRecord::Base.establish_connection configuration
end
end
请注意,通过执行此操作,您无法在两个不同数据库的同一操作中进行查询。您可以再次调用 change_database 但是当您尝试使用执行查询的方法时,从不再链接到正确数据库的对象开始,它会变得很糟糕。此外,显然您将无法连接属于不同数据库的表。
为了正确处理这个问题,应该大大扩展ActiveRecord。现在应该有一个插件来帮助您解决这个问题。一个快速的研究给了我这个:
DB-Charmer:http://kovyrin.github.com/db-charmer/
我愿意尝试一下。让我知道什么对你有用。
答案 2 :(得分:12)
我通过使用其他数据库
将其添加到我的模型顶部来解决这个问题class Customer < ActiveRecord::Base
ENV["RAILS_ENV"] == "development" ? host = 'devhost' : host = 'prodhost'
self.establish_connection(
:adapter => "mysql",
:host => "localhost",
:username => "myuser",
:password => "mypass",
:database => "somedatabase"
)
答案 3 :(得分:4)
您还应该查看名为DB Charmer的项目: http://kovyrin.net/2009/11/03/db-charmer-activerecord-connection-magic-plugin/
DbCharmer是一个简单但功能强大的ActiveRecord插件,可以做一些事情:
- 允许您轻松管理AR模型的连接(
switch_connection_to
方法)- 允许您将AR模型的默认连接切换到单独的服务器/数据库
- 允许您轻松选择查询的位置(
on_*
方法系列)- 允许您自动向您的从服务器发送读取查询,而主服务器将处理所有更新。
- 将多个数据库迁移添加到ActiveRecord
醇>
答案 4 :(得分:2)
值得注意的是,在所有这些解决方案中,您需要记住关闭自定义数据库连接。 将用完连接,否则会看到奇怪的请求超时问题。
一个简单的解决方案是clear_active_connections!在你的控制器的after_filter中。
after_filter :close_custom_db_connection
def close_custom_db_connection
MyModelWithACustomDBConnection.clear_active_connections!
end
答案 5 :(得分:0)
做了类似这样的事情
default: &default
adapter: postgresql
encoding: unicode
pool: 5
development:
<<: *default
database: mysite_development
test:
<<: *default
database: mysite_test
production:
<<: *default
host: 10.0.1.55
database: mysite_production
username: postgres_user
password: <%= ENV['DATABASE_PASSWORD'] %>
db2_development:
<<: *default
database: db2_development
db2_test:
<<: *default
database: db2_test
db2_production:
<<: *default
host: 10.0.1.55
database: db2_production
username: postgres_user
password: <%= ENV['DATABASE_PASSWORD'] %>
然后在您的模型中,您可以使用
引用db2class Customers < ActiveRecord::Base
establish_connection "db2_#{Rails.env}".to_sym
end
答案 6 :(得分:0)
您在问题中描述的是多租户(结构相同的数据库,每个数据库中包含不同的数据)。 Apartment gem对此非常有用。
对于Rails中多个数据库的一般问题:ActiveRecord支持多个数据库,但Rails不提供管理它们的方法。我最近创建了Multiverse gem来解决这个问题。
答案 7 :(得分:0)
到目前为止,我发现的最佳解决方案是:
我们可以采用3种数据库架构。
注意:它们有某些优缺点,取决于您的用例。
我是从Blog那里得到的!对我来说很有帮助。
您可以将Apartment宝石用于轨道
您可以在Gorails for apartment上观看视频参考
答案 8 :(得分:0)
从 Rails 6 开始,支持多个数据库:https://guides.rubyonrails.org/active_record_multiple_databases.html#generators-and-migrations
对于迟到且显而易见的答案感到抱歉,但认为它是可行的,因为它现在得到支持。