私は同じ問題を抱えていて、答えを見つけるのに非常に長い時間を費やしました! fog_public = falseを設定すると、CarrierWave は config.asset_host を無視することがわかりました。config.fog_public = trueを設定することでこれをデモできます: URL は S3 URL ではなく CloudFront URL になります。この問題は以前に提起されています。
https://github.com/carrierwaveuploader/carrierwave/issues/1158
https://github.com/carrierwaveuploader/carrierwave/issues/1215
最近のプロジェクトでは、S3 へのアップロードを処理するために CarrierWave を使用して満足していましたが、Model.attribute_urlを使用するときに署名付きの CloudFront URL を返すことを望んでいました。私は次の(確かに醜い)回避策を思いつきました。他の人が恩恵を受けたり、改善したりできることを願っています。
「cloudfront-signer」 gem をプロジェクトに追加し、指示に従って構成します。次に、/lib/carrierwave/uploader/url.rbの次のオーバーライドをconfig/initializersの新しいファイルに追加します ( AWS::CF::Signer.sign_urlの複数の挿入に注意してください)。
module CarrierWave
module Uploader
module Url
extend ActiveSupport::Concern
include CarrierWave::Uploader::Configuration
include CarrierWave::Utilities::Uri
##
# === Parameters
#
# [Hash] optional, the query params (only AWS)
#
# === Returns
#
# [String] the location where this file is accessible via a url
#
def url(options = {})
if file.respond_to?(:url) and not file.url.blank?
file.method(:url).arity == 0 ? AWS::CF::Signer.sign_url(file.url) : AWS::CF::Signer.sign_url(file.url(options))
elsif file.respond_to?(:path)
path = encode_path(file.path.gsub(File.expand_path(root), ''))
if host = asset_host
if host.respond_to? :call
AWS::CF::Signer.sign_url("#{host.call(file)}#{path}")
else
AWS::CF::Signer.sign_url("#{host}#{path}")
end
else
AWS::CF::Signer.sign_url((base_path || "") + path)
end
end
end
end # Url
end # Uploader
end # CarrierWave
次に、同じファイルの末尾に以下を追加して、/lib/carrierwave/storage/fog.rbをオーバーライドします。
require "fog"
module CarrierWave
module Storage
class Fog < Abstract
class File
include CarrierWave::Utilities::Uri
def url
# Delete 'if statement' related to fog_public
public_url
end
end
end
end
end
最後に、config/initializers/carrierwave.rb で:
config.asset_host = " http://d12345678.cloudfront.net "
config.fog_public = false
それでおしまい。Model.attribute_url を使用できるようになりました。署名された CloudFront URL が、CarrierWave によって S3 バケットにアップロードされたプライベート ファイルに返されます。