Module: Voltron::Upload::Base::ClassMethods

Defined in:
lib/voltron/upload/active_record/base.rb

Instance Method Summary collapse

Instance Method Details

#mount_uploader(*args) ⇒ Object



9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# File 'lib/voltron/upload/active_record/base.rb', line 9

def mount_uploader(*args)
  super *args

  column = args.first.to_sym

  attr_accessor "cache_#{column}"

  before_validation do
    uploader = self.class.uploaders[column]

    # Catches instances where a user submitted the form without actually uploading anything
    send(column).retrieve_from_store!(self.attributes[column.to_s]) if !send(column).present? && self.attributes[column.to_s].present?

    begin
      cache_id = send("cache_#{column}")
      send(column).retrieve_from_cache!(cache_id) if cache_id.present?
    rescue ::CarrierWave::InvalidParameter => e
      # Invalid cache id, we don't need to do anything but skip it
    end
  end
end

#mount_uploaders(*args) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/voltron/upload/active_record/base.rb', line 31

def mount_uploaders(*args)
  super *args

  column = args.first.to_sym

  attr_accessor "cache_#{column}"

  before_validation do
    uploader = self.class.uploaders[column]
    cache_ids = (send("cache_#{column}") rescue []) || []

    # Store the existing files
    files = send(column)

    cache_ids.each do |cache_id|
      begin
        # Retrieve files from the cache and add them to the list of files
        file = uploader.new(self, column)
        file.retrieve_from_cache!(cache_id)
        files << file
      rescue ::CarrierWave::InvalidParameter => e
        # Invalid cache id, we don't need to do anything but skip it
      end
    end

    # Set the files
    send("#{column}=", files)
  end

  # Only required for multiple uploads. Since Carrierwave does not have any way to remove individual files
  # we must identify each file to be removed individually, remove it from the array of existing files,
  # then reset the value of our mounted files
  after_validation do
    # Only attempt to remove files if there are no validation errors
    if errors.empty?
      # Merge any new uploads with the pre-existing uploads (so we can "add" new files, instead of overwriting)
      uploads = Array.wrap(send(column))

      # Get the ids of uploads we want to remove
      removals = Array.wrap(send("remove_#{column}"))

      removals.each do |removal|
        uploads.reject! { |upload| upload.id == removal }
      end

      # Initially ensure carrierwave DOESN'T think we want to remove ALL files, we're just going to change the files (i.e. - remove some, not all)
      send("remove_#{column}=", false)

      # Ensure that nil is assigned as the value if we indeed have no more files
      send("remove_#{column}!") if uploads.empty?

      assign_attributes(column => uploads)
    end
  end
end