2011-09-06 189 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很好,所以我也加入了它。谢谢。 –