2011-09-06 192 views
13

我生產asset_host的配置是這樣的:軌3.1無法在督促編制資產因資產宿主配置

config.action_controller.asset_host = Proc.new { |source, request| 
    if request.ssl? 
     "#{request.protocol}#{request.host_with_port}" 
    else 
     "#{request.protocol}assets#{(source.length % 4) + 1}.example.com" 
    end 
    } 

...這是或多或少直接從文檔:

http://api.rubyonrails.org/classes/ActionView/Helpers/AssetTagHelper.html

當我去資產:預編譯,我得到這個:

$ RAILS_ENV=production bundle exec rake assets:precompile 
rake aborted! 
This asset host cannot be computed without a request in scope. Remove 
the second argument to your asset_host Proc if you do not need the 
request. 

.... EXCE因爲我需要 知道請求是否是ssl,所以我無法真正刪除第二個arg。也就是說,我知道 請求在rake任務期間不存在以產生資產....

那麼,我該如何擺脫這個問題呢?

回答

18

當(1)你的資產使用的路徑,例如這會發生:

background:url(image_path('awesome-background.gif')) 

和(2)你的asset_host被設置爲的λ/ PROC,需要第二個參數( request)。

你的選擇是要麼刪除request參數(如果你不實際使用的話)或使其可選的(和處理的情況下它是nil)。這是很容易在Ruby 1.9的(應該更容易,見注):

config.action_controller.asset_host = ->(source, request = nil, *_){ 
    # ... just be careful that request can be nil 
} 

如果你想使用Ruby 1.8兼容的,有創造與默認參數的PROC /λ沒有直接的方法,但你可以使用:

config.action_controller.asset_host = Proc.new do |*args| 
    source, request = args 
    # ... 
end 

還是你使用的方法是:

def MyApp.compute_asset_host(source, request = nil) 
    # ... 
end 

config.action_controller.asset_host = MyApp.method(:compute_asset_host) 

注:

  1. 你塊可以返回nil以表示「默認主機」,沒有必要使用"#{request.protocol}#{request.host_with_port}"
  2. 從理論上講,你不需要指定協議;一個以//開頭的url應該使用默認協議(http或https)。我在說「應該」,因爲它看起來像IE <= 8 will download the css assets twice,我遇到了PDFkit的問題。

所以你的具體情況,您asset_host可以簡化爲:

config.action_controller.asset_host = Proc.new { |source, request = nil, *_| 
    "//assets#{(source.length % 4) + 1}.example.com" if request && !request.ssl? 
} 

編輯:使用lambda否則*_避免 bug feature of Ruby

+0

不應該說'如果request && request.ssl?'是'除非request && request.ssl? –

+0

@EricKoslow:哦,對了,我反轉了部分條件。固定,我認爲:-) –

+1

這是一個夢幻般的答案,請標記爲正確的! –

3

對於ruby 1.8.x,@ Marc-Andre的method(:compute_asset_host)技術對我無效。儘管該方法是直接在上面定義的,但是提出了NameError: undefined method `compute_asset_host' for class `Object'

下面是我工作:

config.action_controller.asset_host = Proc.new do |*args| 
    source, request = args 
    if request.try(:ssl?) 
    'ssl.cdn.mysite.com' 
    else 
    'cdn%d.mysite.com' % (source.hash % 4) 
    end 
end 
+0

我用一個明確的範圍編輯了我的示例,使其更清晰。你建議的Proc很好,所以我也加入了它。謝謝。 –