CarrierWave Documentation

repository·master·Indexed 27 days ago

https://github.com/carrierwaveuploader/carrierwave

A flexible file upload gem for Ruby applications, compatible with Rack-based frameworks like Ruby on Rails and various ORMs. It provides features for file storage, processing, versioning (e.g., thumbnails), and security via extension and content type allowlists. Supports local file storage and Amazon S3 via fog-aws, as well as remote URL uploads and ActiveRecord integration for single or multiple file uploads.

Tokens
9.7K
Snippets
40
Records
53
Agent score
94%

What's inside CarrierWave

  1. Optimize large file uploads

    master

    By default, CarrierWave copies files twice (cache then store). For large files, you can improve performance by overriding move_to_cache and move_to_store to return true, which tells CarrierWave to move the file instead of copying it. This has been tested with the local filesystem store.

    class MyUploader < CarrierWave::Uploader::Base
      def move_to_cache
        true
      end
    
      def move_to_store
        true
      end
    end
  2. Generate and use a basic Uploader

    master

    You can generate a new uploader using the Rails generator:

    rails generate uploader Avatar

    This creates app/uploaders/avatar_uploader.rb. A basic uploader implementation looks like this:

    class AvatarUploader < CarrierWave::Uploader::Base
      storage :file
    end

    You can use the uploader class directly to store and retrieve files:

    uploader = AvatarUploader.new
    uploader.store!(my_file)
    uploader.retrieve_from_store!('my_file.png')
  3. Configure Amazon S3 storage using Fog AWS

    master

    To use Amazon S3, add gem "fog-aws" to your Gemfile. You must configure fog_credentials and fog_directory (the bucket name) in a CarrierWave initializer. It is assumed the bucket already exists.

    Required S3 permissions for CarrierWave:

    • s3:ListBucket
    • s3:PutObject
    • s3:GetObject
    • s3:DeleteObject
    • s3:PutObjectAcl

    In your uploader class, set storage :fog.

    # 1. Add to Gemfile
    gem "fog-aws"
    
    # 2. Configure in initializer
    CarrierWave.configure do |config|
      config.fog_credentials = {
        provider:              'AWS',                        # required
        aws_access_key_id:     'xxx',                        # required unless using use_iam_profile
        aws_secret_access_key: 'yyy',                        # required unless using use_iam_profile
        use_iam_profile:       true,                         # optional, defaults to false
        region:                'eu-west-1',                  # optional, defaults to 'us-east-1'
        host:                  's3.example.com',             # optional, defaults to nil
        endpoint:              'https://s3.example.com:8080' # optional, defaults to nil
      }
      config.fog_directory  = 'name_of_bucket'                                      # required
      config.fog_public     = false                                                 # optional, defaults to true
      config.fog_attributes = { cache_control: "public, max-age=#{365.days.to_i}" } # optional, defaults to {}
    end
    
    # 3. Set storage in uploader
    class AvatarUploader < CarrierWave::Uploader::Base
      storage :fog
    end
  4. Upgrade from CarrierWave 2.x to 3.x

    master

    CarrierWave 3.0 changed how file extensions are handled during conversion. If you use process convert: :format, the file extension of the cached or stored file may change. This can cause issues in blue-green deployments where 2.x and 3.x share the same storage.

    To preserve 2.x behavior, set force_extension false immediately after calling process convert: :format.

  5. Configure conditional processing and versions

    master

    You can restrict when processing or version creation occurs using the :if option.

    • Conditional Processing: Use process :method, :if => :predicate_method.
    • Conditional Versions: Use version :name, if: :predicate_method.

    Inside the uploader, the model variable refers to the instance the uploader is attached to. Predicate methods can check model attributes or inspect the file itself (e.g., using MiniMagick).

    class MyUploader < CarrierWave::Uploader::Base
      # Conditional processing
      process :scale => [200, 200], :if => :image?
      
      # Conditional versions
      version :human, if: :is_human?
      version :banner, if: :is_landscape?
    
      def image?(file)
        true
      end
    
      private
    
      def is_human?
        model.can_program?(:ruby)
      end
    
      def is_landscape?
        image = MiniMagick::Image.new(file.path)
        image[:width] > image[:height]
      end
    end
  6. Manipulate images using RMagick

    master

    To use RMagick for image processing, include CarrierWave::RMagick in your uploader. You can use the process callback to trigger manipulation methods like resize_to_fill or convert whenever a file is uploaded.

    class AvatarUploader < CarrierWave::Uploader::Base
      include CarrierWave::RMagick
    
      process resize_to_fill: [200, 200]
      process convert: 'png'
    end
  7. Support multiple file uploads with ActiveRecord

    master

    To support multiple files, you must use mount_uploaders (plural) and a database column that supports arrays or JSON.

    1. Migration: Create a JSON or string column:
    # For PostgreSQL/MySQL
    rails g migration add_avatars_to_users avatars:json
    # For SQLite
    rails g migration add_avatars_to_users avatars:string
    1. Model Configuration:
    class User < ApplicationRecord
      mount_uploaders :avatars, AvatarUploader
      serialize :avatars, JSON # Required if using SQLite
    end
    1. Form and Controller: In your view, use multiple: true:
    <%= form.file_field :avatars, multiple: true %>

    In your controller, permit the attribute as an empty array:

    params.require(:user).permit(:email, :first_name, :last_name, {avatars: []})
    1. Accessing files:
    u.avatars[0].url # => '/url/to/file.png'
    class User < ApplicationRecord
      mount_uploaders :avatars, AvatarUploader
      serialize :avatars, JSON
    end
  8. Handle file uploads across form redisplays

    master

    To prevent uploaded files from disappearing when validation fails, add a hidden field named [attribute]_cache to your form. In Rails, ensure the attribute is included in your attr_accessible list if applicable.

    <%= form_for @user, html: { multipart: true } do |f| %>
      <p>
        <label>My Avatar</label>
        <%= f.file_field :avatar %>
        <%= f.hidden_field :avatar_cache %>
      </p>
    <% end %>
  9. Add multiple versions to an uploader

    master

    You can define multiple versions of a file (e.g., thumbnails) within an uploader class. Use the version block to define specific processing for that version. Note that top-level process calls are executed before versions are created, which can optimize processing costs.

    To access a version's URL, use uploader.version_name.url.

    class MyUploader < CarrierWave::Uploader::Base
      include CarrierWave::MiniMagick
    
      process resize_to_fit: [800, 800]
    
      version :thumb do
        process resize_to_fill: [200,200]
      end
    end
    
    # Usage:
    uploader = MyUploader.new
    uploader.store!(my_file)
    uploader.url # => original processed file
    uploader.thumb.url # => thumbnail version
  10. Configure Rackspace Cloud Files storage using Fog

    master

    To use Rackspace Cloud Files, add gem "fog" to your Gemfile. You must configure fog_credentials (including rackspace_username and rackspace_api_key) and fog_directory (the container) in an initializer.

    It is highly recommended to set config.asset_host to your CDN hostname to avoid unnecessary lookups on every request.

    # 1. Add to Gemfile
    gem "fog"
    
    # 2. Configure in initializer (US-based account)
    CarrierWave.configure do |config|
      config.fog_credentials = {
        provider:           'Rackspace',
        rackspace_username: 'xxxxxx',
        rackspace_api_key:  'yyyyyy',
        rackspace_region:   :ord                      # optional, defaults to :dfw
      }
      config.fog_directory = 'name_of_directory'
      config.asset_host = "http://c000000.cdn.rackspacecloud.com"
    end
    
    # 3. Set storage in uploader
    class AvatarUploader < CarrierWave::Uploader::Base
      storage :fog
    end
  11. Create versions from existing versions

    master

    To improve performance, you can create a version from an already processed version instead of the original file using the from_version: option. This is useful when generating a sequence of increasingly smaller images.

    class MyUploader < CarrierWave::Uploader::Base
      version :thumb do
        process resize_to_fill: [280, 280]
      end
    
      version :small_thumb, from_version: :thumb do
        process resize_to_fill: [20, 20]
      end
    end
  12. Mount CarrierWave on an ActiveRecord model

    master

    To use CarrierWave with ActiveRecord, ensure you load the extension (usually automatic in Rails, but required if loading manually):

    require 'carrierwave/orm/activerecord'
    1. Create a migration to add a string column for the file path:
    rails g migration add_avatar_to_users avatar:string
    rails db:migrate
    1. Mount the uploader in your model:
    class User < ApplicationRecord
      mount_uploader :avatar, AvatarUploader
    end
    1. Assign files to the attribute. Files are cached immediately and stored when the record is saved:
    u = User.new
    u.avatar = params[:file]
    u.save!
    
    # Accessing file info
    u.avatar.url            # => '/url/to/file.png'
    u.avatar.current_path    # => 'path/to/file.png'
    u.avatar_identifier      # => 'file.png'

    Note: u.avatar always returns an object. To check if a file exists, use u.avatar.file.nil?.