2015-04-23 41 views
5

我需要在rails 4中提供一些ip地址來設置某些路由的約束。 有沒有辦法從配置文件中獲取這些數據而不將其編碼到路由文件中?使用訪問路由內的APP_CONFIG ['var']?或提供變量的路線?

林像應用程序變量YAML文件和初始化:

APP_CONFIG = YAML.load_file("#{Rails.root}/config/application.yml")[Rails.env] 

所以通常我可以這樣做:

constraints(:ip => %w[APP_CONFIG['app_url']]) do 
    .. my routes.. 
    end 

這種失敗在routes.rb中有沒有辦法解決這個問題?

+0

當您檢查路由文件中的APP_CONFIG時會發生什麼? –

回答

0

看看rails的初始化過程(http://guides.rubyonrails.org/initialization.html)。你會發現路由實際上比較早(比application.rb或其他初始化器早)加載。因此它尚未加載此文件。

一個辦法解決,這將是把這個到您的boot.rb:

# Set up gems listed in the Gemfile. 
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) 
#Now load app config: 
require 'yaml' 
APP_CONFIG = YAML.load_file(File.expand_path('../../config/application.yml', __FILE__)) 
+0

會有副作用嗎?你的解決方案似乎是正確的,但恐怕它有副作用,儘管它將它作爲正確的答案。 – Rubytastic

+0

這也需要一個require'yaml',然後在Rails.root上仍然失敗,因爲'':未初始化的常量Rails(NameError) – Rubytastic

+0

然後添加require'rails'會拋出更多的錯誤,如WARN:Unresolved在Gem :: Specification.reset期間的規格:所以這似乎有點不可解決。也許我應該允許這些路由,但只是在控制器級別內進行身份驗證。雖然切斷路線本來會更好。任何人的想法? – Rubytastic

1

routes.rb文件是被實例化一次,並加載到內存紅寶石文件。

你可以只添加它裏面的Ruby代碼,它會被執行一次:

Rails.application.routes.draw do 
    app_config = YAML.load_file("#{Rails.root}/config/application.yml")[Rails.env] 
    constraints(:ip => %w[app_config['app_url']]) do 
    .. my routes.. 
    end 
end 

這將實例從YML和可用加載整個軌道路線的應用程序的變量的routes.rb文件。你甚至不需要使用env變量。局部變量似乎是一個好主意。

你也可以把邏輯中,並使其與環境相關:

if Rails.env.production? 
    app_config = YAML.load_file("#{Rails.root}/config/application.yml")[Rails.env] 
    constraints(:ip => %w[app_config['app_url']]) do 
    .. my routes.. 
    end 
else 
    .. my routes ... 
end 
0

我相信你正在運行到一個加載順序問題。你可能會破解這個,但...

我強烈建議使用費加羅來解決這個問題。這是一個專門爲導軌配置設計的gem,可以很好地與12個因素的應用程序部署(如Heroku)配合使用:https://github.com/laserlemon/figaro

我在應用程序中使用費加羅,目前正在使用並能夠確認訪問env變量在我的路線文件中。我相信這個寶石將解決你目前的問題和其他配置問題,你甚至不知道你還沒有!