首页 > 解决方案 > 如何在 gem 和父应用程序中配置 ActiveRecord 连接?

问题描述

精简版:

如何在 Rails 应用程序和 gem 中基于相同的config/database.yml. 配置仅在schema_search_path值上有所不同

长版:

我有一个 Rails 应用程序(级),我将它的一部分提取到一个 gem(级)中。子应用程序只是一个拥有自己模型的宝石。不是导轨引擎或可安装的导轨引擎。它的模型将存在于同一个 Postgres 数据库中,但存在于一个单独的模式中。例如,应用程序模型在public模式中,应用程序模型在child模式中。

作为旁注,我正在使用 gem 管理迁移并在父级standalone-migrations级上分别运行迁移,因此级在其架构中拥有自己的表schema_migrations

Rails 允许包含数据库配置,schema_search_path因此我计划使用它来提供两种配置。

我想避免将 复制config/database.ymlschema_search_pathgem,因为除了每个环境之外,文件都是 100% 相同的。

我的想法(这是行不通的)是在子gem 中使用railtie初始化回调来设置Child::ApplicationRecord.configurations = conf_with_the_correct_schema_search_path

使用这种方法,模型(例如使用 访问Child::Name.all)工作,但手动添加的配置(在 railtie 中)也被用于应用程序。由于schema_search_pathis中唯一的模式,因此child将找不到任何父模型。

在 Rails 控制台中手动分配配置时,我可以访问两个应用程序的模型,直到我这样做ModelBaseClass.establish_connection,这将使用最新的配置并使模型或模型无法访问。例如

子配置示例:

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

标签: ruby-on-railsactiverecord

解决方案


推荐阅读