Rails version 5.2
SidekiqバックグラウンドジョブでZipファイルを作成するには、Amazon s3でRails Active StorageのパブリックURLにアクセスする必要があるシナリオがあります。
実際のファイルURLを取得するのが困難です。私はフォローしようとしました
Rails_blob_url
しかし、それは私に以下を与えます
http://localhost:3000/Rails/active_storage/blobs/eyJfcmFpbHMiOnsibWVzc2FnZSI6IkJBaHBBZUk9IiwiZXhwIjpudWxsLCJwdXIiOiJibG9iX2lkIn19--9598613be650942d1ee4382a44dad679a80d2d3b/sample.pdf
Sidekiqを介して実際のファイルのURLにアクセスするにはどうすればよいですか?
storage.yml
test:
service: Disk
root: <%= Rails.root.join("tmp/storage") %>
local:
service: Disk
root: <%= Rails.root.join("storage") %>
development:
service: S3
access_key_id: 'xxxxx'
secret_access_key: 'xxxxx'
region: 'xxxxx'
bucket: 'xxxxx'
development.rb
config.active_storage.service = :development
私はWebインターフェイスでこれらにうまくアクセスできますが、sidekiq内ではできません
ActiveStorage::Blob#service_url
を使用します。たとえば、単一のheader_image
が添付されたPost
モデルを想定すると:
@post.header_image.service_url
私のユースケースは、バケット内のすべての画像にパブリックアクセスできるS3に画像をアップロードして、リクエストのオリジンまたはURLの有効期限に関係なく、ジョブが後でそれらを取得できるようにすることでした。これが私がやった方法です。 (レール5.2.2)
最初に、新しいS3のデフォルトでは、すべてを非公開にして、2つのステップがあることを無効にします。
_{
"Version": "2008-10-17",
"Statement": [
{
"Sid": "AllowPublicRead",
"Effect": "Allow",
"Principal": "*",
"Action": "s3:GetObject",
"Resource": "arn:aws:s3:::your-bucket-name/*"
}
]
}
_
Block public and cross-account access if bucket has public policies
_がfalse
に設定されていることを確認してくださいこれで、URLの_blob.key
_だけでS3バケット内のすべてにアクセスできます。期限切れのトークンはもう必要ありません。
第二に、そのURLを生成するには、@ Christian_Butzkeのソリューションを使用できます:@post.header_image.service.send(:object_for, @post.header_image.key).public_url
ただし、object_forはservice
のプライベートメソッドであり、public_sendを指定して呼び出すとエラーが発生することに注意してください。そのため、別の代替方法は、@ George_Claghornごとにservice_urlを使用し、url&.split("?")&.first
を持つすべてのパラメーターを削除することです。前述のように、これはローカルホストで失敗し、ホストが見つからないというエラーが発生する場合があります。
これが私のソリューション、またはS3に保存され、デフォルトで公開されているアップロード可能な「ロゴ」です。
_#/models/company.rb
has_one_attached :logo
def public_logo_url
if self.logo&.attachment
if Rails.env.development?
self.logo_url = Rails.application.routes.url_helpers.Rails_blob_url(self.logo, only_path: true)
else
self.logo_url = self.logo&.service_url&.split("?")&.first
end
end
#set a default lazily
self.logo_url ||= ActionController::Base.helpers.asset_path("default_company_icon.png")
end
_
お楽しみください^ _ ^
すべてのファイルを公開する必要がある場合は、アップロードを公開する必要があります。
Config/storage.ymlファイル内
Amazon:
service: S3
access_key_id: zzz
secret_access_key: zzz
region: zzz
bucket: zzz
upload:
acl: "public-read"
コード内
attachment = ActiveStorage::Attachment.find(90)
attachment.blob.service_url # returns large URI
attachment.blob.service_url.sub(/\?.*/, '') # remove query params
次のようなものが返されます: " https://foo.s3.amazonaws.com/bar/buz/2yoQMbt4NvY3gXb5x1YcHpRa "
上記の設定により、パブリックで読み取り可能です。
少し遅れますが、次のような公開URLを取得することもできます(上記の例のように、head_imageが1つ添付されているPostモデルを想定しています)。
@post.header_image.service.send(:object_for, @post.header_image.key).public_url