17

さまざまなクライアントの PostgreSQL スキーマを使用して、マルチテナント Rails アプリケーションに取り組んでいます。Rails の移行はそのままでは複数のスキーマでは機能しないため、すべてのスキーマを移行する次の rake タスクを作成しましたが、機能しているようです。私の質問は、他の人がより優れたエレガントなソリューションを実装しているかどうかです。また、複数のスキーマを使用した PostgreSQL の Rails コードの例を含む優れたチュートリアルがあれば、本当に嬉しく思います。これまでのところ、このテーマに関する優れたプレゼンテーションのみを見つけましたhttp://aac2009.confreaks.com/06-feb-2009-14-30-writing-multi-tenant-applications-in-rails-guy-naor.htmlおよび私が目指しているものの例 tomayko.com/writings/rails-multiple-connections

desc 'Migrates all postgres schemas'
task :schemas do
  # get all schemas
  env = "#{RAILS_ENV}"
  config = YAML::load(File.open('config/database.yml'))
  ActiveRecord::Base.establish_connection(config[env])
  schemas = ActiveRecord::Base.connection.select_values("select * from pg_namespace where nspname != 'information_schema' AND nspname NOT LIKE 'pg%'")
  puts "Migrate schemas: #{schemas.inspect}"
  # migrate each schema
  schemas.each do |schema|
    puts "Migrate schema: #{schema}"
    config = YAML::load(File.open('config/database.yml'))
    config[env]["schema_search_path"] = schema
    ActiveRecord::Base.establish_connection(config[env])
    ActiveRecord::Base.logger = Logger.new(STDOUT)
    ActiveRecord::Migrator.migrate('db/migrate', ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
  end
end
4

4 に答える 4

11

私が使用する schema_utils ライブラリがあり、移行を処理するための次の方法があります。

  def self.with_schema(schema_name, &block)
    conn = ActiveRecord::Base.connection
    old_schema_search_path = conn.schema_search_path
    conn.schema_search_path = schema_name
    begin
      yield
    ensure
      conn.schema_search_path = old_schema_search_path
    end
  end

次に、通常どおり移行を使用して、引き続き rake:migrate を呼び出すことができます。これで、移行で以下を使用できます。

...
schemas.each do |schema|
  SchemaUtils.with_schema(schema) do
    #Put migration code here
    #e.g. add_column :xyz, ...
  end
end

私はスキーマをアカウント コードにマッピングする傾向があるため、次のことを行います。

Account.for_each do |account|
  SchemaUtils.with_schema(account.code) do
    #Put migration code here
  end
end
于 2010-07-07T12:49:41.973 に答える
1

apartmentそのためだけに構築された gem を確認してください。すばらしい。

于 2015-09-17T15:00:50.233 に答える
0

質問が正しかったかどうかはわかりませんが、database.ymlそれぞれに異なる「データベース」を指定して、さらにいくつかの環境を宣言する必要はありませんか?

于 2010-06-28T05:30:50.093 に答える
0

これらのシナリオ、つまり複数のアプリケーションが同じデータベースを共有する状況のために、pg_migrate を作成しました。これを処理する Rails の方法 (エンジン?) はおそらくありますが、データベースを必要とする Rails ではない別のアプリを頻繁に使用しています。

この場合、pg_migrate の重要な機能は、Ruby gem を生成できることです。そのため、すべてのダウンストリーム アプリケーションとは別にデータベース スキーマを維持することが可能になりますが、すべてがそれを参照できます。

Rails Gemfile で、pg_migrate の「package」コマンドを使用して ruby​​ gem をビルドした後、次の操作を実行できます。

gem 'my_db', gem 'jam_db', :path=> "../my_db/gem_package"
于 2014-01-16T17:38:10.120 に答える