Module: CarrierWave::Uploader

Defined in:
lib/carrierwave/uploader.rb

Overview

An uploader is a class that allows you to easily handle the caching and storage of uploaded files. Please refer to the README for configuration options.

Once you have an uploader you can use it in isolation:

my_uploader = MyUploader.new
my_uploader.cache!(File.open(path_to_file))
my_uploader.retrieve_from_store!('monkey.png')

Alternatively, you can mount it on an ORM or other persistence layer, with CarrierWave::Mount#mount_uploader. There are extensions for activerecord and datamapper these are very simple (they are only a dozen lines of code), so adding your own should be trivial.

Defined Under Namespace

Modules: ClassMethods

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#fileObject (readonly)

ClassMethods



181
182
183
# File 'lib/carrierwave/uploader.rb', line 181

def file
  @file
end

#modelObject (readonly)

ClassMethods



181
182
183
# File 'lib/carrierwave/uploader.rb', line 181

def model
  @model
end

#mounted_asObject (readonly)

ClassMethods



181
182
183
# File 'lib/carrierwave/uploader.rb', line 181

def mounted_as
  @mounted_as
end

Class Method Details

.append_features(base) ⇒ Object

:nodoc:



20
21
22
23
# File 'lib/carrierwave/uploader.rb', line 20

def self.append_features(base) #:nodoc:
  super
  base.extend(ClassMethods)
end

.generate_cache_idObject

Generates a unique cache id for use in the caching system

Returns

String

a cache id in the format YYYYMMDD-HHMM-PID-RND



32
33
34
# File 'lib/carrierwave/uploader.rb', line 32

def self.generate_cache_id
  Time.now.strftime('%Y%m%d-%H%M') + '-' + Process.pid.to_s + '-' + ("%04d" % rand(9999))
end

Instance Method Details

#blank?Boolean

Returns

Boolean

Whether the uploaded file is blank

Returns:

  • (Boolean)


217
218
219
# File 'lib/carrierwave/uploader.rb', line 217

def blank?
  !file or file.blank?
end

#cache(new_file) ⇒ Object

Caches the given file unless a file has already been cached, stored or retrieved.

Parameters

new_file (File, IOString, Tempfile)

any kind of file object

Raises

CarrierWave::FormNotMultipart

if the assigned parameter is a string



414
415
416
# File 'lib/carrierwave/uploader.rb', line 414

def cache(new_file)
  cache!(new_file) unless file
end

#cache!(new_file) ⇒ Object

Caches the given file. Calls process! to trigger any process callbacks.

Parameters

new_file (File, IOString, Tempfile)

any kind of file object

Raises

CarrierWave::FormNotMultipart

if the assigned parameter is a string



429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
# File 'lib/carrierwave/uploader.rb', line 429

def cache!(new_file)
  new_file = CarrierWave::SanitizedFile.new(new_file)
  raise CarrierWave::FormNotMultipart if new_file.is_path?

  unless new_file.empty?
    if extension_white_list and not extension_white_list.include?(new_file.extension.to_s)
      raise CarrierWave::IntegrityError, "You are not allowed to upload #{new_file.extension.inspect} files, allowed types: #{extension_white_list.inspect}"
    end

    self.cache_id = CarrierWave::Uploader.generate_cache_id unless cache_id

    @file = new_file

    @filename = new_file.filename
    self.original_filename = new_file.filename

    if CarrierWave.config[:cache_to_cache_dir]
      @file = @file.copy_to(cache_path, CarrierWave.config[:permissions])
    end

    process!

    versions.each do |name, v|
      v.send(:cache_id=, cache_id)
      v.cache!(new_file)
    end
  end
end

#cache_dirObject

Override this in your Uploader to change the directory where files are cached.

Returns

String

a directory



388
389
390
# File 'lib/carrierwave/uploader.rb', line 388

def cache_dir
  CarrierWave.config[:cache_dir]
end

#cache_nameObject

Returns a String which uniquely identifies the currently cached file for later retrieval

Returns

String

a cache name, in the format YYYYMMDD-HHMM-PID-RND/filename.txt



399
400
401
# File 'lib/carrierwave/uploader.rb', line 399

def cache_name
  File.join(cache_id, [version_name, original_filename].compact.join('_')) if cache_id and original_filename
end

#cached?Boolean

Returns:

  • (Boolean)


377
378
379
# File 'lib/carrierwave/uploader.rb', line 377

def cached?
  @cache_id
end

#current_pathObject Also known as: path

Returns

String

the path where the file is currently located.



235
236
237
# File 'lib/carrierwave/uploader.rb', line 235

def current_path
  file.path if file.respond_to?(:path)
end

#extension_white_listObject

Override this method in your uploader to provide a white list of extensions which are allowed to be uploaded.

Returns

NilClass, Array

a white list of extensions which are allowed to be uploaded

Examples

def extension_white_list
  %w(jpg jpeg gif png)
end


369
# File 'lib/carrierwave/uploader.rb', line 369

def extension_white_list; end

#filenameObject

Override this in your Uploader to change the filename.

Be careful using record ids as filenames. If the filename is stored in the database the record id will be nil when the filename is set. Don’t use record ids unless you understand this limitation.

Do not use the version_name in the filename, as it will prevent versions from being loaded correctly.

Returns

String

a filename



324
325
326
# File 'lib/carrierwave/uploader.rb', line 324

def filename
  @filename
end

#identifierObject

Returns a string that uniquely identifies the last stored file

Returns

String

uniquely identifies a file



284
285
286
# File 'lib/carrierwave/uploader.rb', line 284

def identifier
  file.identifier if file.respond_to?(:identifier)
end

#initialize(model = nil, mounted_as = nil) ⇒ Object

If a model is given as the first parameter, it will stored in the uploader, and available throught #model. Likewise, mounted_as stores the name of the column where this instance of the uploader is mounted. These values can then be used inside your uploader.

If you do not wish to mount your uploaders with the ORM extensions in -more then you can override this method inside your uploader.

Parameters

model (Object)

Any kind of model object

mounted_as (Symbol)

The name of the column where this uploader is mounted

Examples

class MyUploader
  include CarrierWave::Uploader

  def store_dir
    File.join('public', 'files', mounted_as, model.permalink)
  end
end


207
208
209
210
# File 'lib/carrierwave/uploader.rb', line 207

def initialize(model=nil, mounted_as=nil)
  @model = model
  @mounted_as = mounted_as
end

#process!Object

Apply all process callbacks added through CarrierWave.process



224
225
226
227
228
# File 'lib/carrierwave/uploader.rb', line 224

def process!
  self.class.processors.each do |method, args|
    self.send(method, *args)
  end
end

#publicObject

Returns

String

the directory where files will be publically accessible



351
352
353
# File 'lib/carrierwave/uploader.rb', line 351

def public
  CarrierWave.config[:public]
end

#readObject

Read the contents of the file

Returns

String

contents of the file



295
296
297
# File 'lib/carrierwave/uploader.rb', line 295

def read
  file.read if file.respond_to?(:read)
end

#retrieve_from_cache(cache_name) ⇒ Object

Retrieves the file with the given cache_name from the cache, unless a file has already been cached, stored or retrieved.

Parameters

cache_name (String)

uniquely identifies a cache file



466
467
468
469
# File 'lib/carrierwave/uploader.rb', line 466

def retrieve_from_cache(cache_name)
  retrieve_from_cache!(cache_name) unless file
rescue CarrierWave::InvalidParameter
end

#retrieve_from_cache!(cache_name) ⇒ Object

Retrieves the file with the given cache_name from the cache.

Parameters

cache_name (String)

uniquely identifies a cache file

Raises

CarrierWave::InvalidParameter

if the cache_name is incorrectly formatted.



482
483
484
485
486
487
# File 'lib/carrierwave/uploader.rb', line 482

def retrieve_from_cache!(cache_name)
  self.cache_id, self.original_filename = cache_name.split('/', 2)
  @filename = original_filename
  @file = CarrierWave::SanitizedFile.new(cache_path)
  versions.each { |name, v| v.retrieve_from_cache!(cache_name) }
end

#retrieve_from_store(identifier) ⇒ Object

Retrieves the file from the storage, unless a file has already been cached, stored or retrieved.

Parameters

identifier (String)

uniquely identifies the file to retrieve



563
564
565
566
# File 'lib/carrierwave/uploader.rb', line 563

def retrieve_from_store(identifier)
  retrieve_from_store!(identifier) unless file
rescue CarrierWave::InvalidParameter
end

#retrieve_from_store!(identifier) ⇒ Object

Retrieves the file from the storage.

Parameters

identifier (String)

uniquely identifies the file to retrieve



575
576
577
578
# File 'lib/carrierwave/uploader.rb', line 575

def retrieve_from_store!(identifier)
  @file = storage.retrieve!(self, identifier)
  versions.each { |name, v| v.retrieve_from_store!(identifier) }
end

#rootObject

Returns

String

the directory that is the root of the application



342
343
344
# File 'lib/carrierwave/uploader.rb', line 342

def root
  CarrierWave.config[:root]
end

#sizeObject

Fetches the size of the currently stored/cached file

Returns

Integer

size of the file



306
307
308
# File 'lib/carrierwave/uploader.rb', line 306

def size
  file.respond_to?(:size) ? file.size : 0
end

#store(new_file) ⇒ Object

Stores the file by passing it to this Uploader’s storage engine, unless a file has already been cached, stored or retrieved.

If CarrierWave.config is true, it will first cache the file and apply any process callbacks before uploading it.

Parameters

new_file (File, IOString, Tempfile)

any kind of file object



533
534
535
# File 'lib/carrierwave/uploader.rb', line 533

def store(new_file)
  store!(new_file) unless file
end

#store!(new_file = nil) ⇒ Object

Stores the file by passing it to this Uploader’s storage engine.

If new_file is omitted, a previously cached file will be stored.

Parameters

new_file (File, IOString, Tempfile)

any kind of file object



546
547
548
549
550
551
552
553
# File 'lib/carrierwave/uploader.rb', line 546

def store!(new_file=nil)
  cache!(new_file) if new_file
  if @file and @cache_id
    @file = storage.store!(self, @file)
    @cache_id = nil
    versions.each { |name, v| v.store!(new_file) }
  end
end

#store_dirObject

Override this in your Uploader to change the directory where the file backend stores files.

Other backends may or may not use this method, depending on their specific needs.

Returns

String

a directory



502
503
504
# File 'lib/carrierwave/uploader.rb', line 502

def store_dir
  CarrierWave.config[:store_dir]
end

#store_path(for_file = filename) ⇒ Object

Calculates the path where the file should be stored. If for_file is given, it will be used as the filename, otherwise CarrierWave::Uploader#filename is assumed.

Parameters

for_file (String)

name of the file <optional>

Returns

String

the store path



518
519
520
# File 'lib/carrierwave/uploader.rb', line 518

def store_path(for_file=filename)
  File.join(store_dir, [version_name, for_file].compact.join('_'))
end

#url(*args) ⇒ Object Also known as: to_s

Returns

String

the location where this file is accessible via a url



262
263
264
265
266
267
268
269
270
271
272
273
# File 'lib/carrierwave/uploader.rb', line 262

def url(*args)
  if(args.first)
    # recursively proxy to version
    versions[args.first.to_sym].url(*args[1..-1])
  else
    if file.respond_to?(:url) and not file.url.blank?
      file.url
    elsif current_path
      File.expand_path(current_path).gsub(File.expand_path(public), '')
    end
  end
end

#version_nameObject

Returns

String

the name of this version of the uploader



333
334
335
# File 'lib/carrierwave/uploader.rb', line 333

def version_name
  self.class.version_names.join('_').to_sym unless self.class.version_names.blank?
end

#versionsObject

Returns a hash mapping the name of each version of the uploader to an instance of it

Returns

Hash=> CarrierWave::Uploader

a list of uploader instances



248
249
250
251
252
253
254
255
# File 'lib/carrierwave/uploader.rb', line 248

def versions
  return @versions if @versions
  @versions = {}
  self.class.versions.each do |name, klass|
    @versions[name] = klass.new(model, mounted_as)
  end
  @versions
end