Pull to refresh

Rails и схемы Postgres

Ruby on Rails *
Tutorial

Вводная


С недавних пор начал в качестве СУБД использовать Postgres. Меня очень сильно привлекают в нем схемы, или как их часто называют — пространство имен(namespace), это конечно не единственное достоинство и даже не главное, а лишь приятная мелочь. Поэтому когда мы с другом начали думать о своем пилотном проекте естественно я в качесстве СУБД выбрал именно Postgres. Но вот поставить его на рельсы так, как хочется, оказалось не так просто для новичка…

Первое что я сделал это создал проект на рельсах:

rails <project name> -d postgresql


Тут все просто, создается базовая струкрура проекта и в database.yml создается уже конфигурация с подключением к postgres:

development:
  adapter: postgresql
  encoding: unicode
  database: app_development
  pool: 5
  username: www
  password: 123
  host: localhost
  port: 5432


Да, чтобы все работало нужно не забыть подключить gem — pg :-)

Проблема


Я столкнулся с тем, что я не могу создать миграцию на создание схемы, точнее я могу ссоздать, но если после этой миграции есть еще одна, которая хочет создать таблицу в этой схеме, то тут начинаются проблемы… Как я понял все миграции запускаются в одной транзакции и поэтому не получается оздать схему и сразу создать в ней таблицу.

В ручную я принципиально не хотел создавать схемы, было желание автоматизировать процесс:

rake db:migrate

и все готово.

Что я пытался сделать


Добавил в database.yml search_path: «app, public» — не помогло, т.к. на момент запуска мигрейшена, создающего схему app, ее еще нет и поэтому приложение не может подключиться к базе. Как только не подходил к search_path, но у меня так и не получилось.

Далее пришло в голову мысль кастомизировать rake-task db:migrate. Крутил ввеертел, не вышло, что-то да шло не так как хочется.

Вариант который меня устроил


Я решил зазложить все миграции по директориям, одну директорию я назвал app — туда я складываю миграции для таблиц, которые принадлежат схеме app, далее создал директорию schema — в ней расположены все миграции, создающие схемы для БД.
Дальше я начал думать, а как же мне запустить лишь те миграции которые лежат в папке schema, а потом лишь все остальные. Я начал посматривать в сторону создания своего rake-task, который выглядит следующим образом:

# -------------------------------------------------------------
# =Description:
# Rake task for creating postgres schemas
# -------------------------------------------------------------
namespace :db do
  desc "Run migration for creating schemas"
  task :create_schemas => :environment do
    ActiveRecord::Migration.verbose = ENV["VERBOSE"] ? ENV["VERBOSE"] == "true" : true
    ActiveRecord::Migrator.migrate("db/migrate/schema", ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
  end
end


Довольно простой таск, на что тут стоит обратить внимание:
  • Таск создается в неймспейсе db
    namespace :db
    
  • Запускаются только миграции из определенной директории
    ActiveRecord::Migrator.migrate("db/migrate/schema", ENV["VERSION"] ? ENV["VERSION"].to_i : nil)
    


Как это все работает


Теперь для накатывания миграций я делаю следующее:
rake db:create_schemas
rake db:migrate

Заключение


Мучить Ruby и RoR я начал совсем недавно, возможно найдется более идеальное решение данной проблемы со схемами в RoR, но текущий вариант меня пока устраивает, может кто-то знает другой, более простой и элегантный способ?
Tags:
Hubs:
Total votes 7: ↑4 and ↓3 +1
Views 14K
Comments Comments 12