carrierwave 3.0.0.beta → 3.0.0.rc

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of carrierwave might be problematic. Click here for more details.

Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +104 -64
  3. data/lib/carrierwave/compatibility/paperclip.rb +4 -2
  4. data/lib/carrierwave/downloader/base.rb +12 -11
  5. data/lib/carrierwave/downloader/remote_file.rb +5 -6
  6. data/lib/carrierwave/locale/en.yml +4 -0
  7. data/lib/carrierwave/mount.rb +31 -82
  8. data/lib/carrierwave/mounter.rb +115 -50
  9. data/lib/carrierwave/orm/activerecord.rb +8 -59
  10. data/lib/carrierwave/processing/mini_magick.rb +13 -11
  11. data/lib/carrierwave/processing/rmagick.rb +7 -11
  12. data/lib/carrierwave/processing/vips.rb +9 -9
  13. data/lib/carrierwave/sanitized_file.rb +47 -37
  14. data/lib/carrierwave/storage/abstract.rb +5 -5
  15. data/lib/carrierwave/storage/file.rb +4 -3
  16. data/lib/carrierwave/storage/fog.rb +69 -50
  17. data/lib/carrierwave/test/matchers.rb +11 -7
  18. data/lib/carrierwave/uploader/cache.rb +17 -9
  19. data/lib/carrierwave/uploader/callbacks.rb +1 -1
  20. data/lib/carrierwave/uploader/configuration.rb +8 -4
  21. data/lib/carrierwave/uploader/dimension.rb +66 -0
  22. data/lib/carrierwave/uploader/file_size.rb +2 -2
  23. data/lib/carrierwave/uploader/processing.rb +21 -7
  24. data/lib/carrierwave/uploader/proxy.rb +16 -3
  25. data/lib/carrierwave/uploader/store.rb +43 -6
  26. data/lib/carrierwave/uploader/url.rb +1 -1
  27. data/lib/carrierwave/uploader/versions.rb +126 -134
  28. data/lib/carrierwave/uploader.rb +2 -0
  29. data/lib/carrierwave/utilities/file_name.rb +2 -2
  30. data/lib/carrierwave/utilities/uri.rb +14 -11
  31. data/lib/carrierwave/validations/active_model.rb +4 -6
  32. data/lib/carrierwave/version.rb +1 -1
  33. data/lib/carrierwave.rb +8 -7
  34. data/lib/generators/uploader_generator.rb +3 -3
  35. metadata +18 -3
  36. /data/lib/generators/templates/{uploader.rb → uploader.rb.erb} +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5777918bb6d5edc1006f2f0bfb10f47e1576bc9b4dcbabbc00d42a0cbd59a93f
4
- data.tar.gz: 3f9a90b9c715e67c753909de2ee5a4c9ff5bd8c51ad5e7ed4730a128690c6a34
3
+ metadata.gz: 52922a42b6cb89c806ceeeb6d88574a2bfa8f02aad4b091c4faaf651445c1d5a
4
+ data.tar.gz: 77ba63dffb7f6274da662bfd850962a930b766fcc4c435bdf0214a3bf30d8c33
5
5
  SHA512:
6
- metadata.gz: c0ff141f52c94d57863789c6255629301317182991e5676394efde778122645da9e38fa9bcac926886e8e8d22d778250803dd8fdd2437d5f4ce3c97dedb2cd3a
7
- data.tar.gz: 4130502d8c30bebf77189f9ca281f2b1cdf285bc6445a260ea3b49bd6597f0e7becad9983d33388eab0ca8f8fcb53e1ae0ebc1b7978c1cca62268e324cb42a2e
6
+ metadata.gz: 2dc4bb4f671e9fc9be1548c110d10f7b92810f59e0d55bd7c70570f2cb1e1c33a4e9698771eef72790231d649bcbe550ed55b54d75154e4d7c246b859137d5aa
7
+ data.tar.gz: 36cce254d5a833491cd5abf772325325d2b67366174eda8c95f2064b5e49ddeec557da938cae12d3427f996f5b002ad3a34a3bc9b7f5f27585cdb162acc92ce7
data/README.md CHANGED
@@ -10,7 +10,7 @@ It works well with Rack based web applications, such as Ruby on Rails.
10
10
 
11
11
  ## Information
12
12
 
13
- * RDoc documentation [available on RubyDoc.info](http://rubydoc.info/gems/carrierwave/frames)
13
+ * RDoc documentation [available on RubyDoc.info](https://rubydoc.info/gems/carrierwave)
14
14
  * Source code [available on GitHub](http://github.com/carrierwaveuploader/carrierwave)
15
15
  * More information, known limitations, and how-tos [available on the wiki](https://github.com/carrierwaveuploader/carrierwave/wiki)
16
16
 
@@ -30,11 +30,20 @@ $ gem install carrierwave
30
30
  In Rails, add it to your Gemfile:
31
31
 
32
32
  ```ruby
33
- gem 'carrierwave', '>= 3.0.0.beta', '< 4.0'
33
+ gem 'carrierwave', '>= 3.0.0.rc', '< 4.0'
34
34
  ```
35
35
 
36
36
  Finally, restart the server to apply the changes.
37
37
 
38
+ ## Upgrading from 2.x or earlier
39
+
40
+ CarrierWave 3.0 comes with a change in the way of handling the file extension on conversion. This results in following issues if you use `process convert: :format` to change the file format:
41
+
42
+ - If you have it on the uploader itself (not within a version), the file extension of the cached file will change. That means if you serve both CarrierWave 2.x and 3.x simultaneously on the same workload (e.g. using blue-green deployment), a cache file stored by 2.x can't be retrieved by 3.x and vice versa.
43
+ - If you have it within a version, the file extension of the stored file will change. You need to perform `#recreate_versions!` to make it usable again.
44
+
45
+ To preserve the 2.x behavior, you can set `force_extension false` right after calling `process convert: :format`. See [#2659](https://github.com/carrierwaveuploader/carrierwave/pull/2659) for the detail.
46
+
38
47
  ## Getting Started
39
48
 
40
49
  Start off by generating an uploader:
@@ -224,6 +233,20 @@ class MyUploader < CarrierWave::Uploader::Base
224
233
  end
225
234
  ```
226
235
 
236
+ ## Changing the filename
237
+
238
+ To change the filename of uploaded files, you can override `#filename` method in the uploader.
239
+
240
+ ```ruby
241
+ class MyUploader < CarrierWave::Uploader::Base
242
+ def filename
243
+ "image.#{file.extension}" # If you upload 'file.jpg', you'll get 'image.jpg'
244
+ end
245
+ end
246
+ ```
247
+
248
+ Some old documentations (like [this](https://stackoverflow.com/a/5865117)) may instruct you to safeguard the filename value with `if original_filename`, but it's no longer necessary with CarrierWave 3.0 or later.
249
+
227
250
  ## Securing uploads
228
251
 
229
252
  Certain files might be dangerous if uploaded to the wrong location, such as PHP
@@ -302,17 +325,8 @@ You no longer need to do this manually.
302
325
 
303
326
  ## Adding versions
304
327
 
305
- Often you'll want to add different versions of the same file. The classic example is image thumbnails. There is built in support for this*:
306
-
307
- *Note:* You must have Imagemagick installed to do image resizing.
308
-
309
- Some documentation refers to RMagick instead of MiniMagick but MiniMagick is recommended.
310
-
311
- To install Imagemagick on OSX with homebrew type the following:
312
-
313
- ```
314
- $ brew install imagemagick
315
- ```
328
+ Often you'll want to add different versions of the same file. The classic example is generating image thumbnails while preserving the original file to be used for high-quality representation.
329
+ In this section we'll explore how CarrierWave supports working with multiple versions. The image manipulation itself is covered in [another section](#manipulating-images).
316
330
 
317
331
  ```ruby
318
332
  class MyUploader < CarrierWave::Uploader::Base
@@ -348,17 +362,7 @@ uploader.thumb.url # => '/url/to/thumb_my_file.png' # size: 200x200
348
362
  One important thing to remember is that process is called *before* versions are
349
363
  created. This can cut down on processing cost.
350
364
 
351
- ### Processing Methods: mini_magick
352
-
353
- - `convert` - Changes the image encoding format to the given format, eg. jpg
354
- - `resize_to_limit` - Resize the image to fit within the specified dimensions while retaining the original aspect ratio. Will only resize the image if it is larger than the specified dimensions. The resulting image may be shorter or narrower than specified in the smaller dimension but will not be larger than the specified values.
355
- - `resize_to_fit` - Resize the image to fit within the specified dimensions while retaining the original aspect ratio. The image may be shorter or narrower than specified in the smaller dimension but will not be larger than the specified values.
356
- - `resize_to_fill` - Resize the image to fit within the specified dimensions while retaining the aspect ratio of the original image. If necessary, crop the image in the larger dimension. Optionally, a "gravity" may be specified, for example "Center", or "NorthEast".
357
- - `resize_and_pad` - Resize the image to fit within the specified dimensions while retaining the original aspect ratio. If necessary, will pad the remaining area with the given color, which defaults to transparent (for gif and png, white for jpeg). Optionally, a "gravity" may be specified, as above.
358
-
359
- See `carrierwave/processing/mini_magick.rb` for details.
360
-
361
- ### conditional process
365
+ ### Conditional processing
362
366
 
363
367
  If you want to use conditional process, you can only use `if` statement.
364
368
 
@@ -442,8 +446,27 @@ class MyUploader < CarrierWave::Uploader::Base
442
446
  end
443
447
  ```
444
448
 
445
- The option `:from_version` uses the file cached in the `:thumb` version instead
446
- of the original version, potentially resulting in faster processing.
449
+ ### Customizing version filenames
450
+
451
+ CarrierWave supports [customization of filename](#changing-the-filename) by overriding an uploader's
452
+ #filename method, but this doesn't work for versions because of the limitation on how CarrierWave
453
+ re-constructs the filename on retrieval of the stored file.
454
+ Instead, you can override `#full_filename` with providing a version-aware name.
455
+
456
+ ```ruby
457
+ class MyUploader < CarrierWave::Uploader::Base
458
+ version :thumb do
459
+ def full_filename(for_file)
460
+ 'thumb.png'
461
+ end
462
+ process convert: 'png'
463
+ end
464
+ end
465
+ ```
466
+
467
+ Please note that `#full_filename` mustn't be constructed based on a dynamic value
468
+ that can change from the time of store and time of retrieval, since it will result in
469
+ being unable to retrieve a file previously stored.
447
470
 
448
471
  ## Making uploads work across form redisplays
449
472
 
@@ -529,12 +552,13 @@ disable CarrierWave's `validate_download` option, you'll need to handle those
529
552
  errors yourself.
530
553
 
531
554
  ### Retry option for download from remote location
532
- If you want to retry the download from the Remote URL, enable the download_retry_count option, an error occurs during download, it will try to execute the specified number of times every 5 second.
555
+ If you want to retry the download from the Remote URL, enable the download_retry_count option, an error occurs during download, it will try to execute the specified number of times.
533
556
  This option is effective when the remote destination is unstable.
534
557
 
535
558
  ```rb
536
559
  CarrierWave.configure do |config|
537
560
  config.download_retry_count = 3 # Default 0
561
+ config.download_retry_wait_time = 3 # Default 5
538
562
  end
539
563
  ```
540
564
 
@@ -839,7 +863,6 @@ Please read the [fog-google README](https://github.com/fog/fog-google/blob/maste
839
863
  For Google Storage JSON API (recommended):
840
864
  ```ruby
841
865
  CarrierWave.configure do |config|
842
- config.fog_provider = 'fog/google'
843
866
  config.fog_credentials = {
844
867
  provider: 'Google',
845
868
  google_project: 'my-project',
@@ -853,7 +876,6 @@ end
853
876
  For Google Storage XML API:
854
877
  ```ruby
855
878
  CarrierWave.configure do |config|
856
- config.fog_provider = 'fog/google'
857
879
  config.fog_credentials = {
858
880
  provider: 'Google',
859
881
  google_storage_access_key_id: 'xxxxxx',
@@ -912,67 +934,81 @@ CarrierWave.configure do |config|
912
934
  end
913
935
  ```
914
936
 
915
- ## Using RMagick
937
+ ## Manipulating images
916
938
 
917
939
  If you're uploading images, you'll probably want to manipulate them in some way,
918
- you might want to create thumbnail images for example. CarrierWave comes with a
919
- small library to make manipulating images with RMagick easier, you'll need to
920
- include it in your Uploader:
940
+ you might want to create thumbnail images for example.
921
941
 
922
- ```ruby
923
- class AvatarUploader < CarrierWave::Uploader::Base
924
- include CarrierWave::RMagick
925
- end
942
+ ### Using MiniMagick
943
+
944
+ MiniMagick performs all the operations using the 'convert' CLI which is part of the standard ImageMagick kit.
945
+ This allows you to have the power of ImageMagick without having to worry about installing
946
+ all the RMagick libraries, it often results in higher memory footprint.
947
+
948
+ See the MiniMagick site for more details:
949
+
950
+ https://github.com/minimagick/minimagick
951
+
952
+ To install Imagemagick on OSX with homebrew type the following:
953
+
954
+ ```
955
+ $ brew install imagemagick
926
956
  ```
927
957
 
928
- The RMagick module gives you a few methods, like
929
- `CarrierWave::RMagick#resize_to_fill` which manipulate the image file in some
930
- way. You can set a `process` callback, which will call that method any time a
931
- file is uploaded.
932
- There is a demonstration of convert here.
933
- Convert will only work if the file has the same file extension, thus the use of the filename method.
958
+ And the ImageMagick command line options for more for what's on offer:
959
+
960
+ http://www.imagemagick.org/script/command-line-options.php
961
+
962
+ Currently, the MiniMagick carrierwave processor provides exactly the same methods as
963
+ for the RMagick processor.
934
964
 
935
965
  ```ruby
936
966
  class AvatarUploader < CarrierWave::Uploader::Base
937
- include CarrierWave::RMagick
967
+ include CarrierWave::MiniMagick
938
968
 
939
969
  process resize_to_fill: [200, 200]
940
- process convert: 'png'
941
-
942
- def filename
943
- super.chomp(File.extname(super)) + '.png' if original_filename.present?
944
- end
945
970
  end
946
971
  ```
947
972
 
948
- Check out the manipulate! method, which makes it easy for you to write your own
949
- manipulation methods.
950
-
951
- ## Using MiniMagick
973
+ #### List of available processing methods:
952
974
 
953
- MiniMagick is similar to RMagick but performs all the operations using the 'convert'
954
- CLI which is part of the standard ImageMagick kit. This allows you to have the power
955
- of ImageMagick without having to worry about installing all the RMagick libraries.
975
+ - `convert` - Changes the image encoding format to the given format(eg. jpg). This operation is treated specially to trigger the change of the file extension, so it matches with the format of the resulting file.
976
+ - `resize_to_limit` - Resize the image to fit within the specified dimensions while retaining the original aspect ratio. Will only resize the image if it is larger than the specified dimensions. The resulting image may be shorter or narrower than specified in the smaller dimension but will not be larger than the specified values.
977
+ - `resize_to_fit` - Resize the image to fit within the specified dimensions while retaining the original aspect ratio. The image may be shorter or narrower than specified in the smaller dimension but will not be larger than the specified values.
978
+ - `resize_to_fill` - Resize the image to fit within the specified dimensions while retaining the aspect ratio of the original image. If necessary, crop the image in the larger dimension. Optionally, a "gravity" may be specified, for example "Center", or "NorthEast".
979
+ - `resize_and_pad` - Resize the image to fit within the specified dimensions while retaining the original aspect ratio. If necessary, will pad the remaining area with the given color, which defaults to transparent (for gif and png, white for jpeg). Optionally, a "gravity" may be specified, as above.
956
980
 
957
- See the MiniMagick site for more details:
981
+ See `carrierwave/processing/mini_magick.rb` for details.
958
982
 
959
- https://github.com/minimagick/minimagick
983
+ ### Using RMagick
960
984
 
961
- And the ImageMagick command line options for more for what's on offer:
985
+ CarrierWave also comes with support for RMagick, a well-known image processing library.
986
+ To use it, you'll need to include this in your Uploader:
962
987
 
963
- http://www.imagemagick.org/script/command-line-options.php
988
+ ```ruby
989
+ class AvatarUploader < CarrierWave::Uploader::Base
990
+ include CarrierWave::RMagick
991
+ end
992
+ ```
964
993
 
965
- Currently, the MiniMagick carrierwave processor provides exactly the same methods as
966
- for the RMagick processor.
994
+ The RMagick module gives you a few methods, like
995
+ `CarrierWave::RMagick#resize_to_fill` which manipulate the image file in some
996
+ way. You can set a `process` callback, which will call that method any time a
997
+ file is uploaded.
998
+ There is a demonstration of convert here.
967
999
 
968
1000
  ```ruby
969
1001
  class AvatarUploader < CarrierWave::Uploader::Base
970
- include CarrierWave::MiniMagick
1002
+ include CarrierWave::RMagick
971
1003
 
972
1004
  process resize_to_fill: [200, 200]
1005
+ process convert: 'png'
973
1006
  end
974
1007
  ```
975
1008
 
1009
+ Check out the manipulate! method, which makes it easy for you to write your own
1010
+ manipulation methods.
1011
+
976
1012
  ## Migrating from Paperclip
977
1013
 
978
1014
  If you are using Paperclip, you can use the provided compatibility module:
@@ -1010,6 +1046,10 @@ errors:
1010
1046
  processing_error: "Failed to manipulate, maybe it is not an image?"
1011
1047
  min_size_error: "File size should be greater than %{min_size}"
1012
1048
  max_size_error: "File size should be less than %{max_size}"
1049
+ min_width_error: "Image width should be greater than %{min_width}px"
1050
+ max_width_error: "Image width should be less than %{max_width}px"
1051
+ min_height_error: "Image height should be greater than %{min_height}px"
1052
+ max_height_error: "Image height should be less than %{max_height}px"
1013
1053
  ```
1014
1054
 
1015
1055
  The [`carrierwave-i18n`](https://github.com/carrierwaveuploader/carrierwave-i18n)
@@ -1104,7 +1144,7 @@ See [CONTRIBUTING.md](https://github.com/carrierwaveuploader/carrierwave/blob/ma
1104
1144
 
1105
1145
  The MIT License (MIT)
1106
1146
 
1107
- Copyright (c) 2008-2015 Jonas Nicklas
1147
+ Copyright (c) 2008 Jonas Nicklas
1108
1148
 
1109
1149
  Permission is hereby granted, free of charge, to any person obtaining
1110
1150
  a copy of this software and associated documentation files (the
@@ -56,10 +56,11 @@ module CarrierWave
56
56
  :basename => lambda{|u, f| u.filename.gsub(/#{File.extname(u.filename)}$/, "") },
57
57
  :extension => lambda{|u, d| File.extname(u.filename).gsub(/^\.+/, "")},
58
58
  :class => lambda{|u, f| u.model.class.name.underscore.pluralize}
59
- }
59
+ }.freeze
60
60
 
61
61
  included do
62
62
  attr_accessor :filename
63
+
63
64
  class_attribute :mappings
64
65
  self.mappings ||= DEFAULT_MAPPINGS.dup
65
66
  end
@@ -92,7 +93,8 @@ module CarrierWave
92
93
  end
93
94
  end
94
95
 
95
- private
96
+ private
97
+
96
98
  def interpolate_paperclip_path(path)
97
99
  mappings.each_pair.inject(path) do |agg, pair|
98
100
  agg.gsub(":#{pair[0]}") { pair[1].call(self, self.paperclip_style).to_s }
@@ -6,6 +6,8 @@ require 'carrierwave/downloader/remote_file'
6
6
  module CarrierWave
7
7
  module Downloader
8
8
  class Base
9
+ include CarrierWave::Utilities::Uri
10
+
9
11
  attr_reader :uploader
10
12
 
11
13
  def initialize(uploader)
@@ -45,7 +47,7 @@ module CarrierWave
45
47
  rescue StandardError => e
46
48
  if @current_download_retry_count < @uploader.download_retry_count
47
49
  @current_download_retry_count += 1
48
- sleep 5
50
+ sleep @uploader.download_retry_wait_time
49
51
  retry
50
52
  else
51
53
  raise CarrierWave::DownloadError, "could not download file: #{e.message}"
@@ -61,17 +63,16 @@ module CarrierWave
61
63
  #
62
64
  # [url (String)] The URL where the remote file is stored
63
65
  #
64
- def process_uri(uri)
65
- uri_parts = uri.split('?')
66
- encoded_uri = Addressable::URI.parse(uri_parts.shift).normalize.to_s
67
- query = uri_parts.any? ? "?#{uri_parts.join('?')}" : ''
68
- begin
69
- URI.parse("#{encoded_uri}#{query}")
70
- rescue URI::InvalidURIError
71
- URI.parse("#{encoded_uri}#{URI::DEFAULT_PARSER.escape(query)}")
72
- end
66
+ def process_uri(source)
67
+ uri = Addressable::URI.parse(source)
68
+ uri.host = uri.normalized_host
69
+ # Perform decode first, as the path is likely to be already encoded
70
+ uri.path = encode_path(decode_uri(uri.path)) if uri.path =~ CarrierWave::Utilities::Uri::PATH_UNSAFE
71
+ uri.query = encode_non_ascii(uri.query) if uri.query
72
+ uri.fragment = encode_non_ascii(uri.fragment) if uri.fragment
73
+ URI.parse(uri.to_s)
73
74
  rescue URI::InvalidURIError, Addressable::URI::InvalidURIError
74
- raise CarrierWave::DownloadError, "couldn't parse URL: #{uri}"
75
+ raise CarrierWave::DownloadError, "couldn't parse URL: #{source}"
75
76
  end
76
77
 
77
78
  ##
@@ -41,11 +41,7 @@ module CarrierWave
41
41
  filename
42
42
  end
43
43
 
44
- def respond_to?(*args)
45
- super || file.respond_to?(*args)
46
- end
47
-
48
- private
44
+ private
49
45
 
50
46
  def filename_from_header
51
47
  return nil unless headers['content-disposition']
@@ -63,7 +59,10 @@ module CarrierWave
63
59
  def method_missing(*args, &block)
64
60
  file.send(*args, &block)
65
61
  end
62
+
63
+ def respond_to_missing?(*args)
64
+ super || file.respond_to?(*args)
65
+ end
66
66
  end
67
67
  end
68
68
  end
69
-
@@ -11,3 +11,7 @@ en:
11
11
  processing_error: "Failed to manipulate, maybe it is not an image?"
12
12
  min_size_error: "File size should be greater than %{min_size}"
13
13
  max_size_error: "File size should be less than %{max_size}"
14
+ min_width_error: "Image width should be greater than %{min_width}px"
15
+ max_width_error: "Image width should be less than %{max_width}px"
16
+ min_height_error: "Image height should be greater than %{min_height}px"
17
+ max_height_error: "Image height should be less than %{max_height}px"
@@ -132,7 +132,7 @@ module CarrierWave
132
132
  # end
133
133
  #
134
134
  def mount_uploader(column, uploader=nil, options={}, &block)
135
- mount_base(column, uploader, options, &block)
135
+ mount_base(column, uploader, options.merge(multiple: false), &block)
136
136
 
137
137
  mod = Module.new
138
138
  include mod
@@ -163,25 +163,13 @@ module CarrierWave
163
163
  end
164
164
 
165
165
  def remote_#{column}_url=(url)
166
- _mounter(:#{column}).remote_urls = [url]
166
+ _mounter(:#{column}).remote_urls = url
167
167
  end
168
168
 
169
169
  def remote_#{column}_request_header=(header)
170
170
  _mounter(:#{column}).remote_request_headers = [header]
171
171
  end
172
172
 
173
- def write_#{column}_identifier
174
- return if frozen?
175
- mounter = _mounter(:#{column})
176
-
177
- if mounter.remove?
178
- mounter.clear!
179
- write_uploader(mounter.serialization_column, nil)
180
- elsif mounter.identifiers.first
181
- write_uploader(mounter.serialization_column, mounter.identifiers.first)
182
- end
183
- end
184
-
185
173
  def #{column}_identifier
186
174
  _mounter(:#{column}).read_identifiers[0]
187
175
  end
@@ -197,27 +185,6 @@ module CarrierWave
197
185
  def #{column}_download_error
198
186
  #{column}_download_errors.last
199
187
  end
200
-
201
- def store_previous_changes_for_#{column}
202
- @_previous_changes_for_#{column} = saved_changes[_mounter(:#{column}).serialization_column]
203
- end
204
-
205
- def reset_previous_changes_for_#{column}
206
- # We use this variable to pass information from save time to commit time.
207
- # Make sure this doesn't persist across multiple transactions
208
- @_previous_changes_for_#{column} = nil
209
- end
210
-
211
- def remove_previously_stored_#{column}
212
- before, after = @_previous_changes_for_#{column}
213
- _mounter(:#{column}).remove_previous([before], [after])
214
- end
215
-
216
- def remove_rolled_back_#{column}
217
- before, after = @_previous_changes_for_#{column}
218
- _mounter(:#{column}).remove_previous([after], [before])
219
- @_previous_changes_for_#{column} = nil
220
- end
221
188
  RUBY
222
189
  end
223
190
 
@@ -310,7 +277,7 @@ module CarrierWave
310
277
  # end
311
278
  #
312
279
  def mount_uploaders(column, uploader=nil, options={}, &block)
313
- mount_base(column, uploader, options, &block)
280
+ mount_base(column, uploader, options.merge(multiple: true), &block)
314
281
 
315
282
  mod = Module.new
316
283
  include mod
@@ -349,52 +316,18 @@ module CarrierWave
349
316
  _mounter(:#{column}).remote_request_headers = headers
350
317
  end
351
318
 
352
- def write_#{column}_identifier
353
- return if frozen?
354
- mounter = _mounter(:#{column})
355
-
356
- if mounter.remove?
357
- mounter.clear!
358
- write_uploader(mounter.serialization_column, nil)
359
- elsif mounter.identifiers.any?
360
- write_uploader(mounter.serialization_column, mounter.identifiers)
361
- end
362
- end
363
-
364
319
  def #{column}_identifiers
365
320
  _mounter(:#{column}).read_identifiers
366
321
  end
367
-
368
- def store_previous_changes_for_#{column}
369
- @_previous_changes_for_#{column} = saved_changes[_mounter(:#{column}).serialization_column]
370
- end
371
-
372
- def reset_previous_changes_for_#{column}
373
- # We use this variable to pass information from save time to commit time.
374
- # Make sure this doesn't persist across multiple transactions
375
- @_previous_changes_for_#{column} = nil
376
- end
377
-
378
- def remove_previously_stored_#{column}
379
- return unless @_previous_changes_for_#{column}
380
- _mounter(:#{column}).remove_previous(*@_previous_changes_for_#{column})
381
- end
382
-
383
- def remove_rolled_back_#{column}
384
- return unless @_previous_changes_for_#{column}
385
- before, after = @_previous_changes_for_#{column}
386
- _mounter(:#{column}).remove_previous(after, before)
387
- @_previous_changes_for_#{column} = nil
388
- end
389
322
  RUBY
390
323
  end
391
324
 
392
- private
325
+ private
393
326
 
394
327
  def mount_base(column, uploader=nil, options={}, &block)
395
328
  include CarrierWave::Mount::Extension
396
329
 
397
- uploader = build_uploader(uploader, &block)
330
+ uploader = build_uploader(uploader, column, &block)
398
331
  uploaders[column.to_sym] = uploader
399
332
  uploader_options[column.to_sym] = options
400
333
 
@@ -419,6 +352,8 @@ module CarrierWave
419
352
 
420
353
  def remove_#{column}!
421
354
  _mounter(:#{column}).remove!
355
+ self.remove_#{column} = true
356
+ write_#{column}_identifier
422
357
  end
423
358
 
424
359
  def remove_#{column}=(value)
@@ -445,22 +380,36 @@ module CarrierWave
445
380
  _mounter(:#{column}).download_errors
446
381
  end
447
382
 
383
+ def write_#{column}_identifier
384
+ _mounter(:#{column}).write_identifier
385
+ end
386
+
448
387
  def mark_remove_#{column}_false
449
388
  _mounter(:#{column}).remove = false
450
389
  end
390
+
391
+ def reset_previous_changes_for_#{column}
392
+ _mounter(:#{column}).reset_changes!
393
+ end
394
+
395
+ def remove_previously_stored_#{column}
396
+ _mounter(:#{column}).remove_previous
397
+ end
398
+
399
+ def remove_rolled_back_#{column}
400
+ _mounter(:#{column}).remove_added
401
+ end
451
402
  RUBY
452
403
  end
453
404
 
454
- def build_uploader(uploader, &block)
455
- return uploader if uploader && !block_given?
405
+ def build_uploader(uploader, column, &block)
406
+ uploader ||= CarrierWave::Uploader::Base
407
+ return uploader unless block_given?
456
408
 
457
- uploader = Class.new(uploader || CarrierWave::Uploader::Base)
458
- const_set("Uploader#{uploader.object_id}".tr('-', '_'), uploader)
409
+ uploader = Class.new(uploader)
410
+ const_set("CarrierWave#{column.to_s.camelize}Uploader", uploader)
459
411
 
460
- if block_given?
461
- uploader.class_eval(&block)
462
- uploader.recursively_apply_block_to_versions(&block)
463
- end
412
+ uploader.class_eval(&block)
464
413
 
465
414
  uploader
466
415
  end
@@ -481,9 +430,9 @@ module CarrierWave
481
430
 
482
431
  def _mounter(column)
483
432
  # We cannot memoize in frozen objects :(
484
- return Mounter.new(self, column) if frozen?
433
+ return Mounter.build(self, column) if frozen?
485
434
  @_mounters ||= {}
486
- @_mounters[column] ||= Mounter.new(self, column)
435
+ @_mounters[column] ||= Mounter.build(self, column)
487
436
  end
488
437
 
489
438
  end # Extension