Reputation: 1767
I want to upload a stringIO as a file to a server. I'm not using rails to make the request, just ruby and some gems. I have created a stringIO like below:
require 'rest-client'
require 'zip'
... some code
stream = Zip::OutputStream::write_buffer do |zip|
... code that download files and packs them
end
stream.rewind
RestClient.post('somepath', { file: stream.read }, headers)
RestClient is just some handy gem that makes it a bit easier to send http request. so my problem is that on the server side in the controller when I receive the request I get an error
ArgumentError - invalid byte sequence in UTF-8:
activesupport (4.2.6) lib/active_support/core_ext/object/blank.rb:117:in `blank?'
carrierwave (0.10.0) lib/carrierwave/sanitized_file.rb:127:in `is_path?'
carrierwave (0.10.0) lib/carrierwave/sanitized_file.rb:93:in `size'
carrierwave (0.10.0) lib/carrierwave/sanitized_file.rb:136:in `empty?'
carrierwave (0.10.0) lib/carrierwave/uploader/cache.rb:119:in `cache!'
carrierwave (0.10.0) lib/carrierwave/mount.rb:329:in `cache'
carrierwave (0.10.0) lib/carrierwave/mount.rb:163:in `export='
carrierwave (0.10.0) lib/carrierwave/orm/activerecord.rb:39:in `export='
app/controllers/exports_controller.rb:17:in `upload'
(I'm using carrierwave to store the files)
I think that I'm not handling the stringIO properly but honestly don't exactly know how should I pass it to the post request so that it behaves like a file
any ideas?
Upvotes: 1
Views: 3574
Reputation: 1767
turns out this was happening because I was not saving the zip as a file but used write_buffer
that responds with stringIO.
stringIO read
method returns a string that was uploaded to my controller and then I tried to save the file using carrierwave roughly like that:
... code in my controller
myObject = ObjectModel.find(params[:id])
myObject.fileUploader = StringIO.new(params[:file]) => this was the string i received from stringIO read method
myObject.save
but it won't work because StringIO objects don't have original_filename
method anymore since Rails3 (As far as I understood from the carrierwave issue page)
The solutions was to create a wrapper around StringIO and add either an attribute or a method that is called original_filename
afterwards file was being saved correctly.
I'm posting link to carrierwave wiki that deals with this:
and a sample wrapper like object
class StringIOWrapper < StringIO
attr_accessor :original_filename
end
afterwards this will work
myObject.fileUploader = StringIOWrapper.new(params[:file])
myObject.save
Upvotes: 1