如何在gem和父应用中配置ActiveRecord连接?

时间:2019-01-07 15:15:56

标签: ruby-on-rails activerecord

简短版本:

如何基于相同的config/database.yml在Rails应用程序和gem(提供相同的源代码)中为ActiveRecord提供单独的配置。这些配置仅在schema_search_path值上有所不同

长版:

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

  

作为旁注,我正在使用standalone-migrations gem管理迁移,并分别在 parent child 上运行迁移,以便 child 得到在其架构中拥有自己的schema_migrations

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

我想避免将config/database.yml复制到 child gem,因为除了每种环境的schema_search_path之外,文件都是100%相同。

我的想法(不起作用)是在 child gem中使用 railtie 初始化程序回调来设置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(...)
  • 子级中的
  • :基于父级配置创建

子配置示例:

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

0 个答案:

没有答案