我正在编写一个开源应用程序,它将由开发人员在他们自己的域上部署。我必须在很多地方引用域名,例如devise的默认邮件程序选项
指定应用程序域名的传统位置在哪里,如何在我的应用程序的其他部分引用它?
答案 0 :(得分:1)
在Rails应用程序中,您可能需要访问与应用程序关联的域的几个区域。根据您需要的代码的特定区域,您有3种不同的情况:
举个例子:
在请求的上下文中(直接或间接)操作的库易于处理。该方法通常是从请求本身检测特定主机名。
虽然在大多数情况下这是实用的,但在其他情况下这有点复杂。一个值得注意的案例是ActiveMailer,它始终位于两个上下文之间。在大多数情况下,电子邮件是在HTTP请求的响应中触发的,但并非总是如此。此外,没有实用的方法将请求上下文从控制器传递到邮件程序,除非您明确地将request.env
作为参数传递给您要发送的每封电子邮件。但这不是最实际的解决方案。
对于简单需求,特别是ActionMailer
,我创建了一个名为actionmailer_with_request
的简单插件,它将请求的上下文存储在当前线程中,并使其可用于ActionMailer
。我在这里提到它主要是为了完整性,但我是第一个承认它不是一个完整的解决方案也不是一个明确的解决方案。它也反对MVC架构。
原因不是明确的解决方案,因为它并没有完全解决在您的电子邮件中提供域名的问题。事实上,如果邮件程序是由后台作业或cron作业触发的,那么您仍然没有请求上下文,因此主机名不会出现。同样,该问题仍适用于需要访问当前主机名的ActionMailer之外的所有系统。它可能是另一个邮件进程,或任何后台/外部进程。
此时,仅仅依赖请求的上下文是不够的。实际上,您可能必须将信息存储在某处。
您可以有几种不同的可能性。没有单一的推荐解决方案。一些替代方案是:
Rails.application.config.hostname = xxxx
在我们的例子中,我们在lib
内有一个名称空间,我们存储了所有与应用程序相关的东西。我们也大量使用环境变量。
因此,假设您的应用程序被称为Something
(因此config/application
中有module Something
),我们就在lib/something.rb
:
module Something
def default_hostname
ENV['SITE_HOST']
end
def default_protocol
ENV['SITE_PROTOCOL']
end
end
这些是方便的包装器,不直接公开环境变量。此外,它允许我们在配置变量,env或我们需要的任何东西之间进行交换,而无需修改代码的任何其他地方。
然后,在config/environments/production.rb
中,您需要更新邮件程序设置:
config.action_mailer.default_url_options = { host: Something.default_hostname, protocol: Something.default_protocol }
如果您希望将设置应用于所有上下文,您还可以决定在config/application.rb
中对其进行配置。
无论您何时需要访问请求上下文之外的主机名,都可以使用
Something.default_hostname
通过方法的便利性是你也可以设置默认值。
module Something
def default_hostname
ENV['SITE_HOST'] || "example.com"
end
end
也许是警告
module Something
def default_hostname
ENV['SITE_HOST'] || begin
warn("Please set SITE_HOST to configure your site URL")
"example.com"
end
end
end
答案 1 :(得分:-1)
如果您愿意,可以在Redis实例中进行设置:
https://github.com/redis/redis-rb
初始设置后
redis.set("mysite_url", "www.foo.com")
# => "OK"
然后在任何需要的地方拨打电话:
redis.get("mysite_url")
# => "www.foo.com"
如果需要,您可以从表单中进行设置,如果您需要从admin进行更改,则非常有用:
redis.set("mysite_url", params[:settings][:site_url])
# => "OK"