Upload file to S3 using CarrierWave without a model, is it possible?
Asked Answered
S

1

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
Superhuman answered 19/11, 2013 at 10:10 Comment(0)
Y
20

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.

Yovonnda answered 19/11, 2013 at 15:27 Comment(3)
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) }Pruitt
I didn't need the retrieve from store line, I just used uploader.url to get the url to my file.Heterogynous
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?Fraya

© 2022 - 2024 — McMap. All rights reserved.