How can I use CarrierWave with ActiveModel (NOT ActiveRecord) in Rails 3

904 views
Skip to first unread message

Derek Harrington

unread,
Apr 24, 2012, 3:56:44 PM4/24/12
to carri...@googlegroups.com
I have a model that does not have a corresponding table in the database, therefore does not extend ActiveRecord, but rather uses ActiveModel.

The mount_uploader function is part of ActiveRecord, so I can't use it. 

Is there a way I can still use the features of CarrierWave to do file uploading without ActiveRecord?

Lawrence

unread,
May 22, 2012, 12:23:32 AM5/22/12
to carrierwave
I encountered the same problem. Any help on this would be greatly
appreciated.

Lawrence

On Apr 25, 3:56 am, Derek Harrington <derekharringto...@gmail.com>
wrote:

Fred Obermann

unread,
May 22, 2012, 11:38:03 AM5/22/12
to carri...@googlegroups.com
Yes, you can use CarrierWave without ActiveRecord.

I am using Mongoid.

In my case I needed a photo-uploader, which would allow me to store photos in an AWS S3 bucket, and which would not overwrite one uploaded file with another, even if the file names were the same, so I followed the steps to create a PhotoUploader class.

To the generated filed I added (or uncommented) the lines:

       storage :fog
       attr_accessor :directory, :file_name, :size

Then I added an

      initialize(directory, file_name, size)

 method.  (all are strings)

Then I re-wrote the  store_dir() and  store_path() methods to something like this:

       def store_dir
           size ?  "#{directory}/#{size}" :   "#{directory}/"
       end

       def store_path()
         store_dir + "/" + downcase_sanitize_and_timestamp_filename(file_name)
       end

This allowed me to store different photos of the same name without one overwriting the other.

I user the term  'directory', but it is just a string, albeit with some embedded slashes (/).

To use this new class, I did something like the following...

        in_file = File.open('/foo/bar/baz.jpg', 'r')
        my_directory = '/f5/3a/56/4b/'
        size = '800'
        fname = File.basename in_file.path
        uploader = PhotoUploader.new(my_directory, fname, size);
        uploader.store!(in_file);
        the_url = uploader.url
        the_key = uploader.store_path

But that's only half the battle, you also have to be able to delete the files that you upload.

In order to do that you have to drop down into the fog (as it were)  do something like this:

     my_public_key = "XYZ...."
     my_private_key = "some.big.honking.string...."

     fog_connection = Fog::Storage.new({
                               :provider                             => 'AWS',
                               :aws_access_key_id           => my_public_key,
                               :aws_secret_access_key    => my_private_key
                               })

     fog_connection.destroy(MY_S3_BUCKET, the_key)


where MY_S3_BUCKET is the name of your S3 bucket.   And my_public_key(S3), and my_private_key(S3) return the aws_access_key_id, and aws_secret_access_key of your AWS account.

Put the code that generates the fog_connection in some singleton class so you don't have to generate more than once.




Reply all
Reply to author
Forward
0 new messages