Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I set content_type using StringIO to upload to S3 using PaperClip

I am using the following code to upload a generated CSV file to S3.

Now, currently the whole process is working, BUT the file is being stored as 'text/plain'. If I change the content type validation to use 'text/csv' it fails with a content type validation error.

I've removed some code for brevity as it is working

class Export < ActiveRecord::Base
    has_attached_file :export_file
    validates_attachment_content_type :export_file, :content_type => "text/plain"
    public  
        def export_leave_requests
            ... csv generated in memory here ... 
            self.update_attributes(export_file: StringIO.new(csv_file))
            self.save!
        end
 end

How do I get this to work to set the content_type as CSV?

like image 561
Craig McGuff Avatar asked Oct 28 '25 06:10

Craig McGuff


1 Answers

I only found one way to get this to conclusively work..

In the model (without this, it is not stored on S3 as text/csv):

has_attached_file :export_file,
    s3_headers: lambda { |attachment|
        {
            'Content-Type' => 'text/csv',
            'Content-Disposition' => "attachment; filename=#{attachment.filename}",
        }
    }

In your export code:

    # read the content from a string, not a file
    file = StringIO.open(csv)

    # fake the class attributes
    file.class.class_eval { attr_accessor :original_filename, :content_type }
    file.original_filename = @export.filename
    file.content_type = 'text/csv'
    # Only needed if you will output contents of the file via to_s 
    file.class.class_eval { alias_method :to_s, :string }

    @export.export_file = file

    # If you don't do this it won't work - I don't know why... 
    @export.export_file.instance_write(:content_type, 'text/csv')

    @export.save!
like image 161
Craig McGuff Avatar answered Oct 31 '25 01:10

Craig McGuff



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!