Как настроить подключение ActiveRecord в геме и родительском приложении? - PullRequest
0 голосов
/ 07 января 2019

Короткая версия:

Как предоставить отдельные конфигурации ActiveRecord в rails app и gem (живущих в одном исходном коде) на основе одного и того же config/database.yml. Конфигурации отличаются только schema_search_path значением

Длинная версия:

У меня есть приложение rails ( parent ), и я извлекаю его часть в гем ( child ). Дочернее приложение - это просто драгоценный камень со своими моделями. Не двигатель рельсов или двигатель рельсов. Его модели будут жить в той же базе данных Postgres, но в отдельной схеме. Например. родительские модели приложений находятся в public схемах, а дочерние модели приложений находятся в child схемах.

В качестве идентификатора я управляю миграциями с помощью standalone-migrations gem и запускаю миграции отдельно на parent и child , поэтому child получает свой собственный schema_migrations таблица в его схеме

Rails позволяет включать в конфигурацию БД schema_search_path, поэтому я планировал использовать ее для предоставления двух конфигураций.

Я бы хотел не копировать config/database.yml в дочерний гем, поскольку файл будет на 100% одинаковым, за исключением schema_search_path для каждой среды.

Моя идея (которая не работает) состояла в том, чтобы использовать railtie обратные вызовы инициализатора в геме child для установки Child::ApplicationRecord.configurations = conf_with_the_correct_schema_search_path

При таком подходе модели child (например, доступ к которым осуществляется с помощью Child::Name.all) работают, но добавленная вручную конфигурация (в railtie) также используется для приложения parent . Поскольку единственная схема в schema_search_path - это child, ни одна из родительских моделей не будет найдена.

При назначении конфигураций вручную в консоли rails я могу получить доступ к обеим моделям приложения, пока я не выполню ModelBaseClass.establish_connection, который будет использовать последнюю конфигурацию и сделает либо parent , либо child модели недоступны. Например.

  • в родитель : ApplicationRecord.configurations = YAML.load(...)
  • in child : создать на основе родительского конфига

Пример дочерней конфигурации:

add_child_schema_lookup = ->(acc, keyval) do
  k, v = keyval
  acc.merge({k => v.merge(schema_search_path: 'child')})
end
child_configs = ApplicationRecord.configurations.reduce({}, &add_child_schema_lookup) 
Child::ApplicationRecord.configurations = child_configs
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...