简短版本:
如何基于相同的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