Posted 3 months ago. Visible to the public. Repeats.

FileIO: Writing strings as Carrierwave uploads

When you have string contents (e.g. a generated binary stream, or data from a remote source) that you want to store as a file using Carrierwave, here is a simple solution.

While you could write your string to a file and pass that file to Carrierwave, why even bother? You already have your string (or stream).
However, a plain StringIO object will not work for Carrierwave's ActiveRecord integration:

Copy
>> Attachment.create!(file: StringIO.new(contents)) TypeError: no implicit conversion of nil into String

This is because Carrierwave expects a filename by default. It makes sense, so here is a simple yet useful helper class:

Copy
class FileIO < StringIO def initialize(stream, filename) super(stream) @original_filename = filename end attr_reader :original_filename end

You must simply come up with a filename and can then pass your string or stream directly.

Copy
>> Attachment.create!(file: FileIO.new(contents, 'document.pdf')) => #<Attachment ...>

By refactoring problematic code and creating automated tests, makandra can vastly improve the maintainability of your Rails application.

Author of this card:

Avatar
Arne Hartherz
Last edit:
3 months ago
by Arne Hartherz
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Arne Hartherz to makandra dev