Ok, so I figured out how to do this, and I will explain below. My guess was correct to use two different CarrierWave bootloader classes - one class designed to boot onto S3 (using the CarrierWave_Direct gem), and a second class used only for image processing (the class I already used in production). I will try to post the appropriate code below, but if anyone has any questions let me know. I'm not sure why I have not seen others using separate classes like this, but it seems to work for me.
My image Uploader class app\uploaders\image_uploader.rb using media: wavewave_direct gem:
class ImageUploader < CarrierWave::Uploader::Base include CarrierWaveDirect::Uploader include ActiveModel::Conversion extend ActiveModel::Naming include CarrierWave::MimeTypes process :set_content_type # 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(jpg jpeg gif png) end # Include the Sprockets helpers for Rails 3.1+ asset pipeline compatibility: include Sprockets::Helpers::RailsHelper include Sprockets::Helpers::IsolatedHelper # Override the directory where uploaded files will be stored. # CarrierWaveDirect::Uploader puts raw uploaded files in this directory on S3 as a first step def store_dir "unprocessed_uploads" end end
** Please note that processing is not performed in this class.
My image PROCESSING the class app\uploaders\image_processor.rb (which was already in production):
class ImageProcessor < CarrierWave::Uploader::Base
My fashion model (in short):
class Photo < ActiveRecord::Base mount_uploader :image, ImageProcessor def save_and_process_image(options = {}) s3_unprocessed_image_url = self.image.asset_host + '/' + self.key
I also have a photo controller and a viewing code if I want it to let me know. I mainly use the ImageUploader class to bootstrap on S3 to a folder called unprocessed_uploads. Then S3 responds with the key field in the URL that I pass to the ImageProcessor class - it is attached to the Photo and processes the thumbnail and other images, and then reloads them into my uploads folder on S3.
This separation meant that I did not need to change the current folder structure to S3 when adding the carrierwave_direct gem. Hope this helps others. Let me know if you need more code. I'm tired of typing :)
UPDATE - adding more code:
Photo controller:
class PhotosController < ApplicationController def index @photos = @photos.sort_by(&:created_at) @uploader = ImageUploader.new @uploader.success_action_redirect = new_tank_photo_url(@tank) respond_to do |format| format.html
Photos Type of pointer, form with "Download" button:
<%= direct_upload_form_for @uploader, :html => {:class => "form-inline"} do |f| %> <%= f.file_field :image %> <%= f.submit "Upload", :class => "btn btn-primary btn-medium" %> <% end %>
Thus, with the above view / controller code, a brief description of the steps taken is provided. Note the difference between the ImageUploader class and the ImageProcessor class:
- In my photo controller, I create the @uploader variable, which has the ImageUploader class - this means that the images presented in my index / view form, which uses @uploader, upload the image to the "temp" folder. Because it uses then the ImageUploader class is not processed when this image is loaded (for now).
- When the user clicks the "Download" button on the form, the action Photo → create is called. This action calls @ photo.save_and_process_image - look at the model to see that this method actually captures the recently downloaded image from the S3 folder 'temp', processes it, and then reloads the processed images to the final destination. This is all possible, because my photomodule is associated with the ImageProcessor class, which performs processing / loading. It is not associated with a separate ImageUploader class.
Hope this helps explain what is going on with me.