Перенос Rails для схем postgreSQL

Я работаю над приложением многопользовательских рельсов, используя схемы PostgreSQL для разных клиентов. Миграция Rails не работает с несколькими схемами из коробки, поэтому я выполнил следующую команду rake, чтобы перенести все схемы и, похоже, работает. Мой вопрос в том, что другие реализовали лучшие и более элегантные решения. Я также был бы очень доволен хорошим учебным пособием, включая примеры кода rails для PostgreSQL с использованием нескольких схем. До сих пор я только нашел хорошую презентацию по теме http://aac2009.confreaks.com/06-feb-2009-14-30-writing-multi-tenant-applications-in-rails-guy-naor.html и пример того, что я стремлюсь для tomayko.com/writings/рельсы и множество соединений

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

Ответ 1

У меня есть библиотека 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

Ответ 2

Я не уверен, правильно ли получил вопрос, но вам просто не нужно объявлять еще несколько сред в вашем database.yml с другой "базой данных", указанной в каждом?

Ответ 3

Я написал pg_migrate из-за этих сценариев, то есть ситуаций, в которых несколько приложений используют одну и ту же базу данных. Вероятно, Rails способ справиться с этим (двигатели?), Но у меня слишком часто есть другое приложение, которое не Rails, которому тоже нужна база данных... то что?

В этом случае ключевая особенность pg_migrate заключается в том, что она может генерировать рубиновый камень; поэтому становится возможным поддерживать схему базы данных отдельно от всех нисходящих приложений, но все могут ссылаться на нее.

В вашем Rails Gemfile, после того как вы создали рубиновый камень с помощью команды pg_migrate 'package', вы можете сделать:

gem 'my_db', gem 'jam_db', :path=> "../my_db/gem_package"

Ответ 4

Проверьте apartment драгоценный камень, который был построен именно для этой цели. Это блестяще.