diff options
author | George Claghorn <george.claghorn@gmail.com> | 2018-05-08 18:46:08 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-05-08 18:46:08 -0400 |
commit | 38ea7bb74d5c3d2ae992c35b6eb731d059aa772a (patch) | |
tree | 8be2f5c25a30ea0f1ad42a8ce74992ac5aa2cdab /activestorage | |
parent | 834be61e61a1ed55f056cdff12ffe4cdcaa7ca65 (diff) | |
parent | 8e98bb7758f081622ab5c4eebf3730cce22ee627 (diff) | |
download | rails-38ea7bb74d5c3d2ae992c35b6eb731d059aa772a.tar.gz rails-38ea7bb74d5c3d2ae992c35b6eb731d059aa772a.tar.bz2 rails-38ea7bb74d5c3d2ae992c35b6eb731d059aa772a.zip |
Merge pull request #32833 from ryandav/activestorage_blob_set_content_type
Add option to ActiveStorage::Blob to set extract_content_type_from_io
Diffstat (limited to 'activestorage')
-rw-r--r-- | activestorage/CHANGELOG.md | 15 | ||||
-rw-r--r-- | activestorage/app/models/active_storage/blob.rb | 17 | ||||
-rw-r--r-- | activestorage/test/models/blob_test.rb | 10 | ||||
-rw-r--r-- | activestorage/test/test_helper.rb | 4 |
4 files changed, 37 insertions, 9 deletions
diff --git a/activestorage/CHANGELOG.md b/activestorage/CHANGELOG.md index 4c12adae56..679ca0df03 100644 --- a/activestorage/CHANGELOG.md +++ b/activestorage/CHANGELOG.md @@ -1,3 +1,18 @@ +* Pass in `identify: false` as an argument when providing a `content_type` for + `ActiveStorage::Attached::{One,Many}#attach` to bypass automatic content + type inference. For example: + + ```ruby + @message.image.attach( + io: File.open('/path/to/file'), + filename: 'file.pdf', + content_type: 'application/pdf', + identify: false + ) + ``` + + *Ryan Davidson* + * The Google Cloud Storage service properly supports streaming downloads. It now requires version 1.11 or newer of the google-cloud-storage gem. diff --git a/activestorage/app/models/active_storage/blob.rb b/activestorage/app/models/active_storage/blob.rb index 0cd4ad8128..b8b3b62f22 100644 --- a/activestorage/app/models/active_storage/blob.rb +++ b/activestorage/app/models/active_storage/blob.rb @@ -44,21 +44,23 @@ class ActiveStorage::Blob < ActiveRecord::Base end # Returns a new, unsaved blob instance after the +io+ has been uploaded to the service. - def build_after_upload(io:, filename:, content_type: nil, metadata: nil) + # When providing a content type, pass <tt>identify: false</tt> to bypass automatic content type inference. + def build_after_upload(io:, filename:, content_type: nil, metadata: nil, identify: true) new.tap do |blob| blob.filename = filename blob.content_type = content_type blob.metadata = metadata - blob.upload io + blob.upload(io, identify: identify) end end # Returns a saved blob instance after the +io+ has been uploaded to the service. Note, the blob is first built, # then the +io+ is uploaded, then the blob is saved. This is done this way to avoid uploading (which may take # time), while having an open database transaction. - def create_after_upload!(io:, filename:, content_type: nil, metadata: nil) - build_after_upload(io: io, filename: filename, content_type: content_type, metadata: metadata).tap(&:save!) + # When providing a content type, pass <tt>identify: false</tt> to bypass automatic content type inference. + def create_after_upload!(io:, filename:, content_type: nil, metadata: nil, identify: true) + build_after_upload(io: io, filename: filename, content_type: content_type, metadata: metadata, identify: identify).tap(&:save!) end # Returns a saved blob _without_ uploading a file to the service. This blob will point to a key where there is @@ -142,13 +144,14 @@ class ActiveStorage::Blob < ActiveRecord::Base # # Prior to uploading, we compute the checksum, which is sent to the service for transit integrity validation. If the # checksum does not match what the service receives, an exception will be raised. We also measure the size of the +io+ - # and store that in +byte_size+ on the blob record. + # and store that in +byte_size+ on the blob record. The content type is automatically extracted from the +io+ unless + # you specify a +content_type+ and pass +identify+ as false. # # Normally, you do not have to call this method directly at all. Use the factory class methods of +build_after_upload+ # and +create_after_upload!+. - def upload(io) + def upload(io, identify: true) self.checksum = compute_checksum_in_chunks(io) - self.content_type = extract_content_type(io) + self.content_type = extract_content_type(io) if content_type.nil? || identify self.byte_size = io.size self.identified = true diff --git a/activestorage/test/models/blob_test.rb b/activestorage/test/models/blob_test.rb index daa01015f7..17151117db 100644 --- a/activestorage/test/models/blob_test.rb +++ b/activestorage/test/models/blob_test.rb @@ -43,6 +43,16 @@ class ActiveStorage::BlobTest < ActiveSupport::TestCase assert_equal "text/plain", blob.content_type end + test "create after upload extracts content_type from io when no content_type given and identify: false" do + blob = create_blob content_type: nil, identify: false + assert_equal "text/plain", blob.content_type + end + + test "create after upload uses content_type when identify: false" do + blob = create_blob data: "Article,dates,analysis\n1, 2, 3", filename: "table.csv", content_type: "text/csv", identify: false + assert_equal "text/csv", blob.content_type + end + test "image?" do blob = create_file_blob filename: "racecar.jpg" assert_predicate blob, :image? diff --git a/activestorage/test/test_helper.rb b/activestorage/test/test_helper.rb index 499d955a2f..573a8e0b0b 100644 --- a/activestorage/test/test_helper.rb +++ b/activestorage/test/test_helper.rb @@ -50,8 +50,8 @@ class ActiveSupport::TestCase end private - def create_blob(data: "Hello world!", filename: "hello.txt", content_type: "text/plain") - ActiveStorage::Blob.create_after_upload! io: StringIO.new(data), filename: filename, content_type: content_type + def create_blob(data: "Hello world!", filename: "hello.txt", content_type: "text/plain", identify: true) + ActiveStorage::Blob.create_after_upload! io: StringIO.new(data), filename: filename, content_type: content_type, identify: identify end def create_file_blob(filename: "racecar.jpg", content_type: "image/jpeg", metadata: nil) |