class CarrierWave::Mounter
:nodoc:
we don’t pollute the model with a lot of methods.
this is an internal class, used by CarrierWave::Mount so that
def self.build(record, column)
def self.build(record, column) if record.class.uploader_options[column][:multiple] Multiple.new(record, column) else Single.new(record, column) end end
def blank?
def blank? uploaders.none?(&:present?) end
def blank_uploader
def blank_uploader uploader_class.new(record, column) end
def cache(new_files)
def cache(new_files) return if !new_files.is_a?(Array) && new_files.blank? old_uploaders = uploaders @uploaders = new_files.map do |new_file| handle_error do if new_file.is_a?(String) if (uploader = old_uploaders.detect { |old_uploader| old_uploader.identifier == new_file }) uploader.staged = true uploader else begin uploader = blank_uploader uploader.retrieve_from_cache!(new_file) uploader rescue CarrierWave::InvalidParameter nil end end else uploader = blank_uploader uploader.cache!(new_file) uploader end end end.reject(&:blank?) @removed_uploaders += (old_uploaders - @uploaders) write_temporary_identifier end
def cache_names
def cache_names uploaders.map(&:cache_name).compact end
def cache_names=(cache_names)
def cache_names=(cache_names) cache_names = cache_names.reject(&:blank?) return if cache_names.blank? clear_unstaged cache_names.each do |cache_name| uploader = blank_uploader uploader.retrieve_from_cache!(cache_name) @uploaders << uploader rescue CarrierWave::InvalidParameter # ignore end write_temporary_identifier end
def clear!
def clear! @removed_uploaders += uploaders @remove = nil @uploaders = [] end
def clear_unstaged
def clear_unstaged uploaders # Ensure that uploaders are initialized based on the current value staged, unstaged = @uploaders.partition(&:staged) @uploaders = staged @removed_uploaders += unstaged end
def handle_error
def handle_error yield rescue CarrierWave::DownloadError => e @download_errors << e raise e unless option(:ignore_download_errors) rescue CarrierWave::ProcessingError => e @processing_errors << e raise e unless option(:ignore_processing_errors) rescue CarrierWave::IntegrityError => e @integrity_errors << e raise e unless option(:ignore_integrity_errors) end
def identifiers
def identifiers uploaders.map(&:identifier) end
def initialize(record, column)
def initialize(record, column) @record = record @column = column @options = record.class.uploader_options[column] @download_errors = [] @processing_errors = [] @integrity_errors = [] @removed_uploaders = [] @added_uploaders = [] end
def option(name)
def option(name) self.uploader_options ||= {} self.uploader_options[name] ||= record.class.uploader_option(column, name) end
def read_identifiers
def read_identifiers [record.read_uploader(serialization_column)].flatten.reject(&:blank?) end
def remote_urls=(urls)
def remote_urls=(urls) if urls.nil? urls = [] else urls = Array.wrap(urls).reject(&:blank?) return if urls.blank? end @download_errors.clear @remote_urls = urls clear_unstaged @remote_urls.zip(remote_request_headers || []) do |url, header| handle_error do uploader = blank_uploader uploader.download!(url, header || {}) @uploaders << uploader end end write_temporary_identifier end
def remove!
def remove! uploaders.each(&:remove!) clear! end
def remove=(value)
def remove=(value) uploaders # Ensure that uploaders are initialized based on the current value @remove = value write_temporary_identifier end
def remove?
def remove? remove.present? && (remove.to_s !~ /\A0|false$\z/) end
def remove_added
def remove_added current_paths = (@removed_uploaders + uploaders.select(&:staged)).map(&:path) @added_uploaders .reject {|uploader| current_paths.include?(uploader.path) } .each { |uploader| uploader.remove! } reset_changes! end
def remove_previous
def remove_previous current_paths = uploaders.map(&:path) @removed_uploaders .reject {|uploader| current_paths.include?(uploader.path) } .each { |uploader| uploader.remove! if uploader.remove_previously_stored_files_after_update } reset_changes! end
def reset_changes!
def reset_changes! @removed_uploaders = [] @added_uploaders = [] end
def serialization_column
def serialization_column option(:mount_on) || column end
def store!
def store! uploaders.each(&:store!) end
def temporary_identifiers
def temporary_identifiers if remove? [] else uploaders.map { |uploader| uploader.temporary_identifier } end end
def uploader_class
def uploader_class record.class.uploaders[column] end
def uploaders
def uploaders @uploaders ||= read_identifiers.map do |identifier| uploader = blank_uploader uploader.retrieve_from_store!(identifier) uploader end end
def urls(*args)
def urls(*args) uploaders.map { |u| u.url(*args) } end
def write_identifier
def write_identifier return if record.frozen? clear! if remove? additions, remains = uploaders.partition(&:cached?) existing_identifiers = (@removed_uploaders + remains).map(&:identifier) additions.each do |uploader| uploader.deduplicate(existing_identifiers) existing_identifiers << uploader.identifier end @added_uploaders += additions record.write_uploader(serialization_column, identifier) end
def write_temporary_identifier
def write_temporary_identifier return if record.frozen? record.write_uploader(serialization_column, temporary_identifier) end