Simplify report file storage

This commit is contained in:
Maikel Linke
2023-10-12 17:37:10 +11:00
committed by Konrad
parent ff6bcb113f
commit 20af19c912
4 changed files with 8 additions and 25 deletions

View File

@@ -14,8 +14,7 @@ class ReportJob < ApplicationJob
report = report_class.new(user, params, render: true)
result = report.render_as(format)
blob = ReportBlob.create_for_upload_later!(filename)
blob.store(result)
blob = ReportBlob.create!(filename, result)
execution_time = Time.zone.now - start_time

View File

@@ -5,34 +5,19 @@ class ReportBlob < ActiveStorage::Blob
# AWS S3 limits URL expiry to one week.
LIFETIME = 1.week
def self.create_for_upload_later!(filename)
# ActiveStorage discourages modifying a blob later but we need a blob
# before we know anything about the report file. It enables us to use the
# same blob in the controller to read the result.
create_before_direct_upload!(
def self.create!(filename, content)
create_and_upload!(
io: StringIO.new(content),
filename:,
byte_size: 0,
checksum: "0",
content_type: content_type(filename),
).tap do |blob|
ActiveStorage::PurgeJob.set(wait: LIFETIME).perform_later(blob)
end
identify: false,
)
end
def self.content_type(filename)
MIME::Types.of(filename).first&.to_s || "application/octet-stream"
end
def store(content)
io = StringIO.new(content)
upload(io, identify: false)
save!
end
def content_stored?
@content_stored ||= reload.checksum != "0"
end
def result
@result ||= download.force_encoding(Encoding::UTF_8)
end

View File

@@ -10,7 +10,7 @@ describe ReportMailer do
blob:,
).report_ready
}
let(:blob) { ReportBlob.create_for_upload_later!("customers.csv") }
let(:blob) { ReportBlob.create!("customers.csv", "report content") }
it "notifies about a report" do
expect(email.subject).to eq "Report ready"

View File

@@ -4,11 +4,10 @@ require 'spec_helper'
describe ReportBlob, type: :model do
it "preserves UTF-8 content" do
blob = ReportBlob.create_for_upload_later!("customers.html")
content = "This works. ✓"
expect do
blob.store(content)
blob = ReportBlob.create!("customers.html", content)
content = blob.result
end.to_not change { content.encoding }.from(Encoding::UTF_8)
end