从数据库中提取一些配置变量以在Rails环境中动态设置?

3

是否可以在production.rb中动态设置某些配置变量,使用来自数据库的值?

我正在构建一个多租户应用程序,每个租户都有一些需要动态设置的环境特定信息。

例如:

// production.rb
config.action_mailer.default_url_options  = { :host => current_tenant.domain }

current_tenant 是一个辅助方法,定义在 ApplicationHelper 中,因此无法在 production.rb 中访问。

这是 current_tenant 的定义:

// application_helper.rb
def current_tenant
  @current_tenant ||= Tenant.find_by(domain: Apartment::Tenant.current)
end

如果不行,是否可以使用数据库数据动态创建 secrets.yml 文件?这样我就能在 production.rb 中使用 ENV 了。

你如何访问当前租户?你能做一个中间件吗? - Mkou
@Mkou添加到问题中。我怎样才能在中间件中实现这个? - Jacob
你可以尝试在邮件发送器中设置URL主机,假设邮件发送器类是UserMailer。UserMailer.default_url_options[:host] = 'domain' - Anant Kolvankar
发送邮件程序只是一个例子,还有其他需要从数据库中获取动态数据的配置变量。 - Jacob
你能给我们提供其他的例子吗? - Mkou
还有一件事,你可以在ApplicationController中添加一个before_filter set_tenant_config,并在该方法中完成所有配置。 - Anant Kolvankar
2个回答

0

这个设置在应用程序启动时运行,因此如果您想要一个选项由某些变量驱动,那么该变量需要对在启动时运行的 Ruby 代码可用。有各种方法可以实现这一点:

  • 启动 Rails 服务器的脚本(或其他内容)通过参数传递
  • 某个其他进程将值写入文本文件中,然后由启动脚本再次读取
  • 同样是这样,但使用环境变量

例如,如果您为每个租户(用户组)提供自己的子域名,则子域名可以用作启动代码读取数据库并提取该租户的某些详细信息的键。然后,在启动应用程序时,将通过该子域名传递给应用程序。

编辑-说了这么多,我不确定是否有必要更改启动配置。您不能只在发送电子邮件时查找适当的域名,而不是更改配置中设置的默认域名吗?


0
也许你可以尝试这个方法: 为你的电子邮件创建一个辅助方法:
def build_tenant_url(route_name, *args)
  opts = args.extract_options!
  opts.merge!(host: @tenant ? @tenant.domain : your_domain)
  #Here you can merge other options if you need to pass a token etc
  Rails.application.routes_url_helpers.send(:"#{route_name}_url", *args, opts)
end

在你的邮件程序中,定义 @tenant 变量。
然后在你的邮件视图中使用它。
= link_to 'Edit', build_tenant_url(:edit_tenant, @tenant) 

邮件发送器只是一个例子,还有其他需要从数据库获取动态数据的配置变量。 - Jacob
你能给我们提供其他的例子吗? - Mkou
另一个例子是初始化器。Devise宝石的初始化器需要Facebook和Google的api_keys(这些密钥对于每个租户都是特定的)。 - Jacob
production.rb 的另一个示例是 Paperclip gem,它使用 Amazon S3 API 密钥进行全局配置(这些密钥再次针对每个租户特定)。 - Jacob
由于配置是在应用程序创建时运行一次,因此您无法以多种方式配置应用程序。 您将需要逐个解决问题。 - Mkou

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接