Rails中的多个数据库

luc*_*uca 51 database activerecord ruby-on-rails

可以这样做吗?在单个应用程序中,使用SQLite管理许多项目.我想要的是为我的应用程序管理的每个项目都有一个不同的数据库..所以同一结构化数据库的多个副本,但其中包含不同的数据.我将根据URI上的params选择使用哪个副本.

这是为1.安全性做的..我是这种编程的新手,我不希望它发生在某个原因上,在工作项目时,另一个被破坏了.2.易于备份和存档旧项目

Sim*_*tti 39

默认情况下,Rails不是为多数据库体系结构而设计的,在大多数情况下,它根本没有意义.但是,您可以使用不同的数据库和连接.

这里有一些参考:


ade*_*ade 27

如果您能够控制和配置每个Rails实例,并且由于它们处于待机状态而可以提供浪费资源,那么请省去一些麻烦,只需更改database.yml即可修改每个实例上使用的数据库连接.如果你担心性能,这种方法不会削减它.

对于仅在一个数据库上绑定到单个唯一表的模型,可以在模型中调用establish_connection:

establish_connection "database_name_#{RAILS_ENV}"
Run Code Online (Sandbox Code Playgroud)

如下所述: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
Run Code Online (Sandbox Code Playgroud)

并将该方法作为before_filter添加到所有控制器:

before_filter :change_database
Run Code Online (Sandbox Code Playgroud)

因此,对于每个控制器的每个操作,当定义并设置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
Run Code Online (Sandbox Code Playgroud)

请注意,通过执行此操作,您无法在两个不同数据库的同一操作中进行查询.您可以再次调用change_database,但是当您尝试使用不再链接到正确数据库的对象执行查询的方法时,它会变得很糟糕.此外,显然您将无法连接属于不同数据库的表.

为了正确处理这个问题,应该大大扩展ActiveRecord.现在应该有一个插件来帮助您解决这个问题.一个快速的研究给了我这个:

DB-Charmer:http://kovyrin.github.com/db-charmer/

我愿意尝试一下.让我知道什么对你有用.


小智 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"
    )
Run Code Online (Sandbox Code Playgroud)