10

CarrierWave has amazing documentation, until you need to do it without a model!

I have my uploader and fog settings set up, and they all work fine when using the mounted uploader on a model, but now I want to do it without a model.

I have this:

 uploader = CsvUploader.new
 something = uploader.store!(File.read(file_path))
 uploader.retrieve_from_store!(self.file_name)

When I call .store! the code runs immediately which is weird since it should take a few seconds to upload the file?

Then after I call .retrieve_from_store! the uploader object has all the correct S3 info, like the full urls and stuff.

However, calling:

uploader.file.exists?

returns false. And browsing the s3 urls return a key not found error from s3.

So, what am I doing wrong?? To reiterate, it works when mounted so I don't think it's my fog settings.

My uploader:

class CsvUploader < CarrierWave::Uploader::Base
  # Choose what kind of storage to use for this uploader:
  storage :fog

  # Override the directory where uploaded files will be stored.
  # This is a sensible default for uploaders that are meant to be mounted:
  include CarrierWave::MimeTypes
  process :set_content_type

  def store_dir
    "uploads/public/extranet_csvs"
  end

  def cache_dir
    "/tmp/uploads"
  end

  # Add a white list of extensions which are allowed to be uploaded.
  # For images you might use something like this:
  def extension_white_list
    %w(csv)
  end
end
andy
  • 8,165
  • 12
  • 71
  • 120

1 Answers1

18

I think you want File.open instead of File.read. The latter returns a raw string, which CarrierWave doesn't know how to store.

uploader = CsvUploader.new
File.open(file_path) do |file|
  something = uploader.store!(file)
end
uploader.retrieve_from_store!(self.file_name)

This could probably be clearer in the docs, but I confirmed it by checking the specs. Bummer that CarrierWave is failing silently here.

Jamon Holmgren
  • 20,854
  • 4
  • 52
  • 69
Taavo
  • 2,398
  • 1
  • 14
  • 17
  • 1
    Great answer, thanks! Just a heads up for anyone using this code - calling `File.open(file_path)` like this will leave the file open after it's stored. To have Ruby close it for you, use `File.open(file_path) { |file| something = uploader.store!(file) }` – Thiago Campezzi May 23 '14 at 07:03
  • I didn't need the retrieve from store line, I just used `uploader.url` to get the url to my file. – Ahmed Fahmy Jan 08 '17 at 18:21
  • When we do uploader.store!(file) it tries to find store_dir and in that method I need to derive the account_id which depends on the model object. But in this case model object is NIL. So is there any way to pass that ID while storing the file? – Sanjay Prajapati Apr 08 '21 at 07:43