我正在編寫一個開源應用程序,將由開發人員在其自己的域中進行部署。有很多地方我必須參考域名,例如devise的默認郵件選項如何在多個域上運行單個代碼庫?
傳統地方指定應用程序的域名,以及如何在我的應用程序的其他部分引用它?
我正在編寫一個開源應用程序,將由開發人員在其自己的域中進行部署。有很多地方我必須參考域名,例如devise的默認郵件選項如何在多個域上運行單個代碼庫?
傳統地方指定應用程序的域名,以及如何在我的應用程序的其他部分引用它?
在Rails應用程序中,可能有幾個區域需要訪問與應用程序關聯的域。根據在你需要它的代碼的特定區域,你有3個不同的情況:在請求
爲了舉個例子的上下文之外運行
庫的範圍之外(例如,如果同樣的方法是通過CLI或後臺作業執行),其在請求(直接或間接)的上下文中操作很容易處理。該方法通常是從請求本身檢測特定的主機名。
雖然在大多數情況下這是實用的,但在其他情況下,這有點複雜。一個值得注意的例子是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
可以將其設置在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"
不幸的是,這仍然不是最好的方法。更好的方法是將其設置爲default_urls:host – amingilani
把它放在一個環境變量 – neo
@ neo的我這樣做,但我幾乎可以肯定有一個更好的辦法。 – amingilani