2016-07-11 18 views
0

我正在編寫一個開源應用程序,將由開發人員在其自己的域中進行部署。有很多地方我必須參考域名,例如devise的默認郵件選項如何在多個域上運行單個代碼庫?

傳統地方指定應用程序的域名,以及如何在我的應用程序的其他部分引用它?

+0

把它放在一個環境變量 – neo

+0

@ neo的我這樣做,但我幾乎可以肯定有一個更好的辦法。 – amingilani

回答

1

在Rails應用程序中,可能有幾個區域需要訪問與應用程序關聯的域。根據在你需要它的代碼的特定區域,你有3個不同的情況:在請求

  • 代碼的請求的範圍之外運行的上下文中運行

    1. 代碼,但它是由請求觸發的(或者可以由請求來觸發),該請求

    爲了舉個例子的上下文之外運行

  • 代碼:

    • 控制器運行到請求的上下文中
    • 模型方法在請求上下文之外執行,但您可以在調用方法時傳遞上下文。然而,這永遠是現在適用
    • 通過調度運行後臺作業或任務是完全的請求

    庫的範圍之外(例如,如果同樣的方法是通過CLI或後臺作業執行),其在請求(直接或間接)的上下文中操作很容易處理。該方法通常是從請求本身檢測特定的主機名。

    雖然在大多數情況下這是實用的,但在其他情況下,這有點複雜。一個值得注意的例子是ActiveMailer,它始終位於兩個上下文之間。在大多數情況下,電子郵件是通過HTTP請求觸發的,但並非總是如此。此外,除非您明確地將request.env作爲參數傳遞給您要發送的每封電子郵件,否則沒有實際的方法可將請求上下文從控制器傳遞到郵件程序。但這不是最實際的解決方案。

    對於簡單的需求,並專門針對ActionMailer,我創建了一個簡單的插件叫做actionmailer_with_request存儲在當前線程的請求的情況下,並且將其提供給ActionMailer。我在這裏提到它主要是爲了完整性,但我是第一個承認它不是一個完整的解決方案。它也違背了MVC架構。

    原因不是最終的解決方案,是因爲它不能完全解決在您的電子郵件中使域名可用的問題。事實上,如果郵件程序是由後臺作業或cron作業觸發的,則仍然沒有請求上下文,因此主機名將不存在。同樣,這個問題仍然適用於需要訪問當前主機名的ActionMailer之外的所有系統。它可能是另一個郵件過程,或者任何背景/外部過程。

    在這一點上,很明顯只依賴請求的上下文是不夠的。事實上,您可能必須將信息存儲在某個地方。

    您可以有幾種不同的可能性。沒有單一的推薦解決方案。一些替代方案是:

    • Rails配置對象,例如Rails.application.config.hostname = xxxx
    • 的配置系統
    • 恆定的Rails應用程序或環境

    在我們的例子中,我們有內部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

    可以將其設置在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" 
    
    +0

    不幸的是,這仍然不是最好的方法。更好的方法是將其設置爲default_urls:host – amingilani

    相關問題