Module: CarrierWave::Mount

Included in:
Card, ActiveRecord, CardMount
Defined in:
vendor/carrierwave/lib/carrierwave/mount.rb

Overview

If a Class is extended with this module, it gains the mount_uploader method, which is used for mapping attributes to uploaders and allowing easy assignment.

You can use mount_uploader with pretty much any class, however it is intended to be used with some kind of persistent storage, like an ORM. If you want to persist the uploaded files in a particular Class, it needs to implement a read_uploader and a write_uploader method.

Defined Under Namespace

Modules: Extension

Instance Method Summary collapse

Instance Method Details

#mount_uploader(column, uploader = nil, options = {}, &block) ⇒ Object

Mounts the given uploader on the given column. This means that assigning and reading from the column will upload and retrieve files. Supposing that a User class has an uploader mounted on image, you can assign and retrieve files like this:

@user.image # => <Uploader>
@user.image.store!(some_file_object)

@user.image.url # => '/some_url.png'

It is also possible (but not recommended) to omit the uploader, which will create an anonymous uploader class.

Passing a block makes it possible to customize the uploader. This can be convenient for brevity, but if there is any significant logic in the uploader, you should do the right thing and have it in its own file.

=== Added instance methods

Supposing a class has used +mount_uploader+ to mount an uploader on a column named +image+, in that case the following methods will be added to the class:

[image] Returns an instance of the uploader only if anything has been uploaded [image=] Caches the given file

[image_url] Returns the url to the uploaded file

[image_cache] Returns a string that identifies the cache location of the file [image_cache=] Retrieves the file from the cache based on the given cache name

[remote_image_url] Returns previously cached remote url [remote_image_url=] Retrieve the file from the remote url

[remove_image] An attribute reader that can be used with a checkbox to mark a file for removal [remove_image=] An attribute writer that can be used with a checkbox to mark a file for removal [remove_image?] Whether the file should be removed when store_image! is called.

[store_image!] Stores a file that has been assigned with +image=+ [remove_image!] Removes the uploaded file from the filesystem.

[image_integrity_error] Returns an error object if the last file to be assigned caused an integrity error [image_processing_error] Returns an error object if the last file to be assigned caused a processing error [image_download_error] Returns an error object if the last file to be remotely assigned caused a download error

[image_identifier] Reads out the identifier of the file

=== Parameters

[column (Symbol)] the attribute to mount this uploader on [uploader (CarrierWave::Uploader)] the uploader class to mount [options (Hash=> Object)] a set of options [&block (Proc)] customize anonymous uploaders

=== Options

[:mount_on => Symbol] if the name of the column to be serialized to differs you can override it using this option [:ignore_integrity_errors => Boolean] if set to true, integrity errors will result in caching failing silently [:ignore_processing_errors => Boolean] if set to true, processing errors will result in caching failing silently

=== Examples

Mounting uploaders on different columns.

class Song
  mount_uploader :lyrics, LyricsUploader
  mount_uploader :alternative_lyrics, LyricsUploader
  mount_uploader :file, SongUploader
end

This will add an anonymous uploader with only the default settings:

class Data
  mount_uploader :csv
end

this will add an anonymous uploader overriding the store_dir:

class Product
  mount_uploader :blueprint do
    def store_dir
      'blueprints'
    end
  end
end


134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'vendor/carrierwave/lib/carrierwave/mount.rb', line 134

def mount_uploader(column, uploader=nil, options={}, &block)
  mount_base(column, uploader, options, &block)

  mod = Module.new
  include mod
  mod.class_eval <<-RUBY, __FILE__, __LINE__+1

    def #{column}
      _mounter(:#{column}).uploaders[0] ||= _mounter(:#{column}).blank_uploader
    end

    def #{column}=(new_file)
      _mounter(:#{column}).cache([new_file])
    end

    def #{column}_url(*args)
      #{column}.url(*args)
    end

    def #{column}_cache
      _mounter(:#{column}).cache_names[0]
    end

    def #{column}_cache=(cache_name)
      _mounter(:#{column}).cache_names = [cache_name]
    end

    def remote_#{column}_url
      [_mounter(:#{column}).remote_urls].flatten[0]
    end

    def remote_#{column}_url=(url)
      _mounter(:#{column}).remote_urls = [url]
    end

    def write_#{column}_identifier
      return if frozen?
      mounter = _mounter(:#{column})

      if mounter.remove?
        write_uploader(mounter.serialization_column, nil)
      elsif mounter.identifiers.first
        write_uploader(mounter.serialization_column, mounter.identifiers.first)
      end
    end

    def #{column}_identifier
      _mounter(:#{column}).read_identifiers[0]
    end

    def store_previous_changes_for_#{column}
      @_previous_changes_for_#{column} = changes[_mounter(:#{column}).serialization_column]
    end

    def remove_previously_stored_#{column}
      before, after = @_previous_changes_for_#{column}
      _mounter(:#{column}).remove_previous([before], [after])
    end
  RUBY
end

#mount_uploaders(column, uploader = nil, options = {}, &block) ⇒ Object

Mounts the given uploader on the given array column. This means that assigning and reading from the array column will upload and retrieve multiple files. Supposing that a User class has an uploader mounted on images, and that images can store an array, for example it could be a PostgreSQL JSON column. You can assign and retrieve files like this:

@user.images # => []
@user.images = [some_file_object]
@user.images # => [<Uploader>]

@user.images[0].url # => '/some_url.png'

It is also possible (but not recommended) to omit the uploader, which will create an anonymous uploader class.

Passing a block makes it possible to customize the uploader. This can be convenient for brevity, but if there is any significant logic in the uploader, you should do the right thing and have it in its own file.

=== Added instance methods

Supposing a class has used +mount_uploaders+ to mount an uploader on a column named +images+, in that case the following methods will be added to the class:

[images] Returns an array of uploaders for each uploaded file [images=] Caches the given files

[images_urls] Returns the urls to the uploaded files

[images_cache] Returns a string that identifies the cache location of the files [images_cache=] Retrieves the files from the cache based on the given cache name

[remote_image_urls] Returns previously cached remote urls [remote_image_urls=] Retrieve files from the given remote urls

[remove_images] An attribute reader that can be used with a checkbox to mark the files for removal [remove_images=] An attribute writer that can be used with a checkbox to mark the files for removal [remove_images?] Whether the files should be removed when store_image! is called.

[store_images!] Stores all files that have been assigned with +images=+ [remove_images!] Removes the uploaded file from the filesystem.

[images_integrity_error] Returns an error object if the last files to be assigned caused an integrity error [images_processing_error] Returns an error object if the last files to be assigned caused a processing error [images_download_error] Returns an error object if the last files to be remotely assigned caused a download error

[image_identifiers] Reads out the identifiers of the files

=== Parameters

[column (Symbol)] the attribute to mount this uploader on [uploader (CarrierWave::Uploader)] the uploader class to mount [options (Hash=> Object)] a set of options [&block (Proc)] customize anonymous uploaders

=== Options

[:mount_on => Symbol] if the name of the column to be serialized to differs you can override it using this option [:ignore_integrity_errors => Boolean] if set to true, integrity errors will result in caching failing silently [:ignore_processing_errors => Boolean] if set to true, processing errors will result in caching failing silently

=== Examples

Mounting uploaders on different columns.

class Song
  mount_uploaders :lyrics, LyricsUploader
  mount_uploaders :alternative_lyrics, LyricsUploader
  mount_uploaders :files, SongUploader
end

This will add an anonymous uploader with only the default settings:

class Data
  mount_uploaders :csv_files
end

this will add an anonymous uploader overriding the store_dir:

class Product
  mount_uploaders :blueprints do
    def store_dir
      'blueprints'
    end
  end
end


283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
# File 'vendor/carrierwave/lib/carrierwave/mount.rb', line 283

def mount_uploaders(column, uploader=nil, options={}, &block)
  mount_base(column, uploader, options, &block)

  mod = Module.new
  include mod
  mod.class_eval <<-RUBY, __FILE__, __LINE__+1

    def #{column}
      _mounter(:#{column}).uploaders
    end

    def #{column}=(new_files)
      _mounter(:#{column}).cache(new_files)
    end

    def #{column}_urls(*args)
      _mounter(:#{column}).urls(*args)
    end

    def #{column}_cache
      names = _mounter(:#{column}).cache_names
      names.to_json if names.present?
    end

    def #{column}_cache=(cache_name)
      _mounter(:#{column}).cache_names = JSON.parse(cache_name) if cache_name.present?
    end

    def remote_#{column}_urls
      _mounter(:#{column}).remote_urls
    end

    def remote_#{column}_urls=(urls)
      _mounter(:#{column}).remote_urls = urls
    end

    def write_#{column}_identifier
      return if frozen?
      mounter = _mounter(:#{column})

      if mounter.remove?
        write_uploader(mounter.serialization_column, nil)
      elsif mounter.identifiers.any?
        write_uploader(mounter.serialization_column, mounter.identifiers)
      end
    end

    def #{column}_identifiers
      _mounter(:#{column}).read_identifiers
    end

    def store_previous_changes_for_#{column}
      @_previous_changes_for_#{column} = changes[_mounter(:#{column}).serialization_column]
    end

    def remove_previously_stored_#{column}
      _mounter(:#{column}).remove_previous(*@_previous_changes_for_#{column})
    end
  RUBY
end

#uploader_option(column, option) ⇒ Object

Return a particular option for a particular uploader

=== Parameters

[column (Symbol)] The column the uploader is mounted at [option (Symbol)] The option, e.g. validate_integrity

=== Returns

[Object] The option value



40
41
42
43
44
45
46
# File 'vendor/carrierwave/lib/carrierwave/mount.rb', line 40

def uploader_option(column, option)
  if uploader_options[column].has_key?(option)
    uploader_options[column][option]
  else
    uploaders[column].send(option)
  end
end

#uploader_optionsObject



24
25
26
# File 'vendor/carrierwave/lib/carrierwave/mount.rb', line 24

def uploader_options
  @uploader_options ||= superclass.respond_to?(:uploader_options) ? superclass.uploader_options.dup : {}
end

#uploadersObject

=== Returns

[Hash=> CarrierWave] what uploaders are mounted on which columns



20
21
22
# File 'vendor/carrierwave/lib/carrierwave/mount.rb', line 20

def uploaders
  @uploaders ||= superclass.respond_to?(:uploaders) ? superclass.uploaders.dup : {}
end