2011-09-06 38 views
13

sản xuất My asset_host cấu hình trông như thế này:ray 3.1 không thể biên dịch tài sản trên sản do tài sản chủ cấu hình

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 
    } 

... đó là nhiều hay ít trực tiếp từ các tài liệu:

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

Khi tôi đi đến tài sản: tiền biên dịch, tôi có được điều này:

$ 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 pt mà tôi không thể thực sự loại bỏ arg thứ 2 bởi vì tôi cần phải biết nếu yêu cầu là ssl hay không. Điều đó nói rằng, tôi hiểu rằng yêu cầu không có trong nhiệm vụ cào để tạo nội dung ....

Vậy làm thế nào để tôi thoát khỏi điều này?

Trả lời

18

này sẽ xảy ra khi (1) tài sản của bạn sử dụng đường dẫn, ví dụ:

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

và (2) của bạn asset_host được đặt thành một lambda/proc mà yêu cầu đối số thứ hai (request).

Tùy chọn của bạn là xóa đối số request (nếu bạn không thực sự sử dụng) hoặc đặt tùy chọn (và xử lý trường hợp là nil). Đây là dễ dàng trong Ruby 1.9 (và nên được dễ dàng hơn, xem ghi chú):

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

Nếu bạn muốn trở thành tương thích với Ruby 1,8, không có cách nào trực tiếp để tạo ra một Proc/lambda với các thông số với giá trị mặc định, nhưng bạn có thể sử dụng:

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

Hay nó sử dụng một phương pháp:

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

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

Ghi chú:

  1. khối của bạn có thể trở lại nil để biểu thị "máy chủ mặc định", không cần phải sử dụng "#{request.protocol}#{request.host_with_port}"
  2. Về lý thuyết bạn không cần phải xác định giao thức; url bắt đầu bằng // nên sử dụng giao thức mặc định (http hoặc https). Tôi đang nói "nên" vì nó trông giống như IE <= 8 will download the css assets twice và tôi đã gặp sự cố với PDFkit.

Vì vậy, trong trường hợp cụ thể của bạn, asset_host của bạn có thể được đơn giản hóa để:

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

Sửa: Sử dụng một lambda hoặc người nào khác *_ để tránh một bug feature of Ruby.

+0

Không phải là 'nếu yêu cầu && request.ssl? 'Là' trừ khi yêu cầu && request.ssl? ' –

+0

@EricKoslow: Ồ, phải, tôi đã đảo ngược một phần của điều kiện. Cố định, tôi nghĩ :-) –

+1

Đây là một câu trả lời tuyệt vời, xin vui lòng đánh dấu là chính xác! –

3

Dành cho ruby ​​1.8.x, kỹ thuật method(:compute_asset_host) của Marc-Andre không hoạt động đối với tôi.Mặc dù phương pháp đã được xác định trực tiếp ở trên, NameError: undefined method `compute_asset_host' for class `Object' đã được nâng lên.

Đây là những gì làm việc cho tôi:

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

Tôi đã chỉnh sửa ví dụ của mình với phạm vi rõ ràng, để làm rõ hơn. Proc được đề xuất của bạn là tốt, vì vậy tôi cũng đã kết hợp nó. Cảm ơn. –

Các vấn đề liên quan