carrierwave 0.11.2 → 3.0.3

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 (69) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +452 -178
  3. data/lib/carrierwave/compatibility/paperclip.rb +4 -4
  4. data/lib/carrierwave/downloader/base.rb +101 -0
  5. data/lib/carrierwave/downloader/remote_file.rb +68 -0
  6. data/lib/carrierwave/error.rb +1 -0
  7. data/lib/carrierwave/locale/en.yml +11 -5
  8. data/lib/carrierwave/mount.rb +212 -182
  9. data/lib/carrierwave/mounter.rb +255 -0
  10. data/lib/carrierwave/orm/activerecord.rb +22 -33
  11. data/lib/carrierwave/processing/mini_magick.rb +140 -84
  12. data/lib/carrierwave/processing/rmagick.rb +72 -21
  13. data/lib/carrierwave/processing/vips.rb +284 -0
  14. data/lib/carrierwave/processing.rb +1 -1
  15. data/lib/carrierwave/sanitized_file.rb +83 -84
  16. data/lib/carrierwave/storage/abstract.rb +16 -3
  17. data/lib/carrierwave/storage/file.rb +71 -3
  18. data/lib/carrierwave/storage/fog.rb +215 -57
  19. data/lib/carrierwave/storage.rb +1 -9
  20. data/lib/carrierwave/test/matchers.rb +88 -19
  21. data/lib/carrierwave/uploader/cache.rb +75 -45
  22. data/lib/carrierwave/uploader/callbacks.rb +1 -3
  23. data/lib/carrierwave/uploader/configuration.rb +80 -16
  24. data/lib/carrierwave/uploader/content_type_allowlist.rb +62 -0
  25. data/lib/carrierwave/uploader/content_type_denylist.rb +62 -0
  26. data/lib/carrierwave/uploader/default_url.rb +3 -5
  27. data/lib/carrierwave/uploader/dimension.rb +66 -0
  28. data/lib/carrierwave/uploader/download.rb +4 -74
  29. data/lib/carrierwave/uploader/extension_allowlist.rb +63 -0
  30. data/lib/carrierwave/uploader/extension_denylist.rb +64 -0
  31. data/lib/carrierwave/uploader/file_size.rb +43 -0
  32. data/lib/carrierwave/uploader/mountable.rb +13 -8
  33. data/lib/carrierwave/uploader/processing.rb +48 -13
  34. data/lib/carrierwave/uploader/proxy.rb +20 -9
  35. data/lib/carrierwave/uploader/remove.rb +0 -2
  36. data/lib/carrierwave/uploader/serialization.rb +2 -4
  37. data/lib/carrierwave/uploader/store.rb +59 -28
  38. data/lib/carrierwave/uploader/url.rb +8 -7
  39. data/lib/carrierwave/uploader/versions.rb +170 -122
  40. data/lib/carrierwave/uploader.rb +12 -10
  41. data/lib/carrierwave/utilities/file_name.rb +47 -0
  42. data/lib/carrierwave/utilities/uri.rb +14 -12
  43. data/lib/carrierwave/utilities.rb +1 -3
  44. data/lib/carrierwave/validations/active_model.rb +7 -11
  45. data/lib/carrierwave/version.rb +1 -1
  46. data/lib/carrierwave.rb +39 -21
  47. data/lib/generators/templates/{uploader.rb → uploader.rb.erb} +5 -9
  48. data/lib/generators/uploader_generator.rb +3 -3
  49. metadata +132 -80
  50. data/lib/carrierwave/locale/cs.yml +0 -11
  51. data/lib/carrierwave/locale/de.yml +0 -11
  52. data/lib/carrierwave/locale/el.yml +0 -11
  53. data/lib/carrierwave/locale/es.yml +0 -11
  54. data/lib/carrierwave/locale/fr.yml +0 -11
  55. data/lib/carrierwave/locale/ja.yml +0 -11
  56. data/lib/carrierwave/locale/nb.yml +0 -11
  57. data/lib/carrierwave/locale/nl.yml +0 -11
  58. data/lib/carrierwave/locale/pl.yml +0 -11
  59. data/lib/carrierwave/locale/pt-BR.yml +0 -11
  60. data/lib/carrierwave/locale/pt-PT.yml +0 -11
  61. data/lib/carrierwave/locale/ru.yml +0 -11
  62. data/lib/carrierwave/locale/sk.yml +0 -11
  63. data/lib/carrierwave/locale/tr.yml +0 -11
  64. data/lib/carrierwave/processing/mime_types.rb +0 -74
  65. data/lib/carrierwave/uploader/content_type_blacklist.rb +0 -48
  66. data/lib/carrierwave/uploader/content_type_whitelist.rb +0 -48
  67. data/lib/carrierwave/uploader/extension_blacklist.rb +0 -47
  68. data/lib/carrierwave/uploader/extension_whitelist.rb +0 -49
  69. data/lib/carrierwave/utilities/deprecation.rb +0 -18
data/README.md CHANGED
@@ -3,36 +3,46 @@
3
3
  This gem provides a simple and extremely flexible way to upload files from Ruby applications.
4
4
  It works well with Rack based web applications, such as Ruby on Rails.
5
5
 
6
- [![Build Status](https://travis-ci.org/carrierwaveuploader/carrierwave.png?branch=master)](http://travis-ci.org/carrierwaveuploader/carrierwave)
7
- [![Code Climate](https://codeclimate.com/github/carrierwaveuploader/carrierwave.png)](https://codeclimate.com/github/carrierwaveuploader/carrierwave)
6
+ [![Build Status](https://github.com/carrierwaveuploader/carrierwave/workflows/Test/badge.svg)](https://github.com/carrierwaveuploader/carrierwave/actions)
7
+ [![Code Climate](https://codeclimate.com/github/carrierwaveuploader/carrierwave.svg)](https://codeclimate.com/github/carrierwaveuploader/carrierwave)
8
+ [![SemVer](https://api.dependabot.com/badges/compatibility_score?dependency-name=carrierwave&package-manager=bundler&version-scheme=semver)](https://dependabot.com/compatibility-score.html?dependency-name=carrierwave&package-manager=bundler&version-scheme=semver)
9
+
8
10
 
9
11
  ## Information
10
12
 
11
- * RDoc documentation [available on RubyDoc.info](http://rubydoc.info/gems/carrierwave/frames)
13
+ * RDoc documentation [available on RubyDoc.info](https://rubydoc.info/gems/carrierwave)
12
14
  * Source code [available on GitHub](http://github.com/carrierwaveuploader/carrierwave)
13
15
  * More information, known limitations, and how-tos [available on the wiki](https://github.com/carrierwaveuploader/carrierwave/wiki)
14
16
 
15
17
  ## Getting Help
16
18
 
17
- * Please ask the [Google Group](http://groups.google.com/group/carrierwave) for help if you have any questions.
19
+ * Please ask the community on [Stack Overflow](https://stackoverflow.com/questions/tagged/carrierwave) for help if you have any questions. Please do not post usage questions on the issue tracker.
18
20
  * Please report bugs on the [issue tracker](http://github.com/carrierwaveuploader/carrierwave/issues) but read the "getting help" section in the wiki first.
19
21
 
20
22
  ## Installation
21
23
 
22
- Install the latest stable release:
24
+ Install the latest release:
23
25
 
24
- [sudo] gem install carrierwave
26
+ ```
27
+ $ gem install carrierwave
28
+ ```
25
29
 
26
30
  In Rails, add it to your Gemfile:
27
31
 
28
32
  ```ruby
29
- gem 'carrierwave'
33
+ gem 'carrierwave', '~> 3.0'
30
34
  ```
31
35
 
32
36
  Finally, restart the server to apply the changes.
33
37
 
34
- Note that CarrierWave is not compatible with Rails 2 as of version 0.5. If you want to use
35
- Rails 2, please use the 0.4-stable branch on GitHub.
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.
36
46
 
37
47
  ## Getting Started
38
48
 
@@ -85,12 +95,12 @@ a migration:
85
95
 
86
96
 
87
97
  rails g migration add_avatar_to_users avatar:string
88
- rake db:migrate
98
+ rails db:migrate
89
99
 
90
100
  Open your model file and mount the uploader:
91
101
 
92
102
  ```ruby
93
- class User < ActiveRecord::Base
103
+ class User < ApplicationRecord
94
104
  mount_uploader :avatar, AvatarUploader
95
105
  end
96
106
  ```
@@ -100,24 +110,103 @@ automatically be stored when the record is saved.
100
110
 
101
111
  ```ruby
102
112
  u = User.new
103
- u.avatar = params[:file]
104
- u.avatar = File.open('somewhere')
113
+ u.avatar = params[:file] # Assign a file like this, or
114
+
115
+ # like this
116
+ File.open('somewhere') do |f|
117
+ u.avatar = f
118
+ end
119
+
105
120
  u.save!
106
121
  u.avatar.url # => '/url/to/file.png'
107
122
  u.avatar.current_path # => 'path/to/file.png'
108
- u.avatar.identifier # => 'file.png'
123
+ u.avatar_identifier # => 'file.png'
109
124
  ```
110
125
 
126
+ **Note**: `u.avatar` will never return nil, even if there is no photo associated to it.
127
+ To check if a photo was saved to the model, use `u.avatar.file.nil?` instead.
128
+
111
129
  ### DataMapper, Mongoid, Sequel
112
130
 
113
131
  Other ORM support has been extracted into separate gems:
114
132
 
115
133
  * [carrierwave-datamapper](https://github.com/carrierwaveuploader/carrierwave-datamapper)
116
134
  * [carrierwave-mongoid](https://github.com/carrierwaveuploader/carrierwave-mongoid)
117
- * [carrierwave-sequel](https://github.com/jnicklas/carrierwave-sequel)
135
+ * [carrierwave-sequel](https://github.com/carrierwaveuploader/carrierwave-sequel)
118
136
 
119
137
  There are more extensions listed in [the wiki](https://github.com/carrierwaveuploader/carrierwave/wiki)
120
138
 
139
+ ## Multiple file uploads
140
+
141
+ CarrierWave also has convenient support for multiple file upload fields.
142
+
143
+ ### ActiveRecord
144
+
145
+ Add a column which can store an array. This could be an array column or a JSON
146
+ column for example. Your choice depends on what your database supports. For
147
+ example, create a migration like this:
148
+
149
+
150
+ #### For databases with ActiveRecord json data type support (e.g. PostgreSQL, MySQL)
151
+
152
+ rails g migration add_avatars_to_users avatars:json
153
+ rails db:migrate
154
+
155
+ #### For database without ActiveRecord json data type support (e.g. SQLite)
156
+
157
+ rails g migration add_avatars_to_users avatars:string
158
+ rails db:migrate
159
+
160
+ __Note__: JSON datatype doesn't exists in SQLite adapter, that's why you can use a string datatype which will be serialized in model.
161
+
162
+ Open your model file and mount the uploader:
163
+
164
+
165
+ ```ruby
166
+ class User < ApplicationRecord
167
+ mount_uploaders :avatars, AvatarUploader
168
+ serialize :avatars, JSON # If you use SQLite, add this line.
169
+ end
170
+ ```
171
+
172
+ Make sure that you mount the uploader with write (mount_uploaders) with `s` not (mount_uploader)
173
+ in order to avoid errors when uploading multiple files
174
+
175
+ Make sure your file input fields are set up as multiple file fields. For
176
+ example in Rails you'll want to do something like this:
177
+
178
+ ```erb
179
+ <%= form.file_field :avatars, multiple: true %>
180
+ ```
181
+
182
+ Also, make sure your upload controller permits the multiple file upload attribute, *pointing to an empty array in a hash*. For example:
183
+
184
+ ```ruby
185
+ params.require(:user).permit(:email, :first_name, :last_name, {avatars: []})
186
+ ```
187
+
188
+ Now you can select multiple files in the upload dialog (e.g. SHIFT+SELECT), and they will
189
+ automatically be stored when the record is saved.
190
+
191
+ ```ruby
192
+ u = User.new(params[:user])
193
+ u.save!
194
+ u.avatars[0].url # => '/url/to/file.png'
195
+ u.avatars[0].current_path # => 'path/to/file.png'
196
+ u.avatars[0].identifier # => 'file.png'
197
+ ```
198
+
199
+ If you want to preserve existing files on uploading new one, you can go like:
200
+
201
+ ```erb
202
+ <% user.avatars.each do |avatar| %>
203
+ <%= hidden_field :user, :avatars, multiple: true, value: avatar.identifier %>
204
+ <% end %>
205
+ <%= form.file_field :avatars, multiple: true %>
206
+ ```
207
+
208
+ Sorting avatars is supported as well by reordering `hidden_field`, an example using jQuery UI Sortable is available [here](https://github.com/carrierwaveuploader/carrierwave/wiki/How-to%3A-Add%2C-remove-and-reorder-images-using-multiple-file-upload).
209
+
121
210
  ## Changing the storage directory
122
211
 
123
212
  In order to change where uploaded files are put, just override the `store_dir`
@@ -144,124 +233,153 @@ class MyUploader < CarrierWave::Uploader::Base
144
233
  end
145
234
  ```
146
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
+
147
250
  ## Securing uploads
148
251
 
149
- Certain file might be dangerous if uploaded to the wrong location, such as php
150
- files or other script files. CarrierWave allows you to specify a white-list of
151
- allowed extensions.
252
+ Certain files might be dangerous if uploaded to the wrong location, such as PHP
253
+ files or other script files. CarrierWave allows you to specify an allowlist of
254
+ allowed extensions or content types.
152
255
 
153
256
  If you're mounting the uploader, uploading a file with the wrong extension will
154
257
  make the record invalid instead. Otherwise, an error is raised.
155
258
 
156
259
  ```ruby
157
260
  class MyUploader < CarrierWave::Uploader::Base
158
- def extension_white_list
261
+ def extension_allowlist
159
262
  %w(jpg jpeg gif png)
160
263
  end
161
264
  end
162
265
  ```
163
266
 
267
+ The same thing could be done using content types.
268
+ Let's say we need an uploader that accepts only images. This can be done like this
269
+
270
+ ```ruby
271
+ class MyUploader < CarrierWave::Uploader::Base
272
+ def content_type_allowlist
273
+ /image\//
274
+ end
275
+ end
276
+ ```
277
+
278
+ You can use a denylist to reject content types.
279
+ Let's say we need an uploader that reject JSON files. This can be done like this
280
+
281
+ ```ruby
282
+ class NoJsonUploader < CarrierWave::Uploader::Base
283
+ def content_type_denylist
284
+ ['application/text', 'application/json']
285
+ end
286
+ end
287
+ ```
288
+
164
289
  ### CVE-2016-3714 (ImageTragick)
165
- This version of CarrierWave has the ability to mitigate CVE-2016-3714. However, you **MUST** set a `content_type_whitelist` in your uploaders for this protection to be effective, and you **MUST** either disable ImageMagick's default SVG delegate or use the RSVG delegate for SVG processing.
290
+ This version of CarrierWave has the ability to mitigate CVE-2016-3714. However, you **MUST** set a content_type_allowlist in your uploaders for this protection to be effective, and you **MUST** either disable ImageMagick's default SVG delegate or use the RSVG delegate for SVG processing.
166
291
 
167
- A valid whitelist that will restrict your uploader to images only, and mitigate the CVE is:
292
+
293
+ A valid allowlist that will restrict your uploader to images only, and mitigate the CVE is:
168
294
 
169
295
  ```ruby
170
296
  class MyUploader < CarrierWave::Uploader::Base
171
- def content_type_whitelist
297
+ def content_type_allowlist
172
298
  [/image\//]
173
299
  end
174
300
  end
175
301
  ```
176
302
 
177
- **WARNING**: A `content_type_whitelist` is the only form of whitelist or blacklist supported by CarrierWave that can effectively mitigate against CVE-2016-3714. Use of `extension_type_whitelist` will not inspect the file headers, and thus still leaves your application open to the vulnerability.
178
-
303
+ **WARNING**: A `content_type_allowlist` is the only form of allowlist or denylist supported by CarrierWave that can effectively mitigate against CVE-2016-3714. Use of `extension_allowlist` will not inspect the file headers, and thus still leaves your application open to the vulnerability.
179
304
 
180
305
  ### Filenames and unicode chars
181
306
 
182
307
  Another security issue you should care for is the file names (see
183
308
  [Ruby On Rails Security Guide](http://guides.rubyonrails.org/security.html#file-uploads)).
184
- By default, CarrierWave provides only English letters, arabic numerals and '-+_.' symbols as
185
- white-listed characters in the file name. If you want to support local scripts (Cyrillic letters, letters with diacritics and so on), you
309
+ By default, CarrierWave provides only English letters, arabic numerals and some symbols as
310
+ allowlisted characters in the file name. If you want to support local scripts (Cyrillic letters, letters with diacritics and so on), you
186
311
  have to override `sanitize_regexp` method. It should return regular expression which would match
187
312
  all *non*-allowed symbols.
188
313
 
189
- With Ruby 1.9 and higher you can simply write (as it has [Oniguruma](http://oniguruma.rubyforge.org/oniguruma/)
190
- built-in):
191
-
192
314
  ```ruby
193
315
  CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/
194
316
  ```
195
317
 
196
- With Ruby 1.8 you have to manually specify all character ranges. For example, for files which may
197
- contain Russian letters:
198
-
199
- ```ruby
200
- CarrierWave::SanitizedFile.sanitize_regexp = /[^a-zA-Zа-яА-ЯёЁ0-9\.\-\+_]/u
201
- ```
202
-
203
318
  Also make sure that allowing non-latin characters won't cause a compatibility issue with a third-party
204
319
  plugins or client-side software.
205
320
 
206
321
  ## Setting the content type
207
322
 
208
- If you care about the content type of your files and notice that it's not being set
209
- as expected, you can configure your uploaders to use `CarrierWave::MimeTypes`.
210
- This adds a dependency on the [mime-types](http://rubygems.org/gems/mime-types) gem,
211
- but is recommended when using fog, and fog already has a dependency on mime-types.
212
-
213
- ```ruby
214
- require 'carrierwave/processing/mime_types'
215
-
216
- class MyUploader < CarrierWave::Uploader::Base
217
- include CarrierWave::MimeTypes
218
-
219
- process :set_content_type
220
- end
221
- ```
323
+ As of v0.11.0, the `mime-types` gem is a runtime dependency and the content type is set automatically.
324
+ You no longer need to do this manually.
222
325
 
223
326
  ## Adding versions
224
327
 
225
- 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*:
226
-
227
- *Note: You must have Imagemagick and MiniMagick installed to do image resizing. MiniMagick is a Ruby interface for Imagemagick which is a C program. This is why MiniMagick fails on 'bundle install' without Imagemagick installed.
228
-
229
- Some documentation refers to RMagick instead of MiniMagick but MiniMagick is recommended.
230
-
231
- To install Imagemagick on OSX with homebrew type the following:
232
-
233
- ```
234
- $ brew install imagemagick
235
- ```
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).
236
330
 
237
331
  ```ruby
238
332
  class MyUploader < CarrierWave::Uploader::Base
239
333
  include CarrierWave::MiniMagick
240
334
 
241
- process :resize_to_fit => [800, 800]
335
+ process resize_to_fit: [800, 800]
242
336
 
243
337
  version :thumb do
244
- process :resize_to_fill => [200,200]
338
+ process resize_to_fill: [200,200]
245
339
  end
246
340
 
247
341
  end
248
342
  ```
249
343
 
250
344
  When this uploader is used, an uploaded image would be scaled to be no larger
251
- than 800 by 800 pixels. A version called thumb is then created, which is scaled
252
- and cropped to exactly 200 by 200 pixels. The uploader could be used like this:
345
+ than 800 by 800 pixels. The original aspect ratio will be kept.
346
+
347
+ A version called `:thumb` is then created, which is scaled
348
+ to exactly 200 by 200 pixels. The thumbnail uses `resize_to_fill` which makes sure
349
+ that the width and height specified are filled, only cropping
350
+ if the aspect ratio requires it.
351
+
352
+ The above uploader could be used like this:
253
353
 
254
354
  ```ruby
255
355
  uploader = AvatarUploader.new
256
356
  uploader.store!(my_file) # size: 1024x768
257
357
 
258
- uploader.url # => '/url/to/my_file.png' # size: 800x600
358
+ uploader.url # => '/url/to/my_file.png' # size: 800x800
259
359
  uploader.thumb.url # => '/url/to/thumb_my_file.png' # size: 200x200
260
360
  ```
261
361
 
262
362
  One important thing to remember is that process is called *before* versions are
263
363
  created. This can cut down on processing cost.
264
364
 
365
+ ### Conditional processing
366
+
367
+ If you want to use conditional process, you can only use `if` statement.
368
+
369
+ See `carrierwave/uploader/processing.rb` for details.
370
+
371
+ ```ruby
372
+ class MyUploader < CarrierWave::Uploader::Base
373
+ process :scale => [200, 200], :if => :image?
374
+
375
+ def image?(carrier_wave_sanitized_file)
376
+ true
377
+ end
378
+ end
379
+ ```
380
+
381
+ ### Nested versions
382
+
265
383
  It is possible to nest versions within versions:
266
384
 
267
385
  ```ruby
@@ -283,11 +401,11 @@ properties within the model or based on the picture itself.
283
401
  ```ruby
284
402
  class MyUploader < CarrierWave::Uploader::Base
285
403
 
286
- version :human, :if => :is_human?
287
- version :monkey, :if => :is_monkey?
288
- version :banner, :if => :is_landscape?
404
+ version :human, if: :is_human?
405
+ version :monkey, if: :is_monkey?
406
+ version :banner, if: :is_landscape?
289
407
 
290
- protected
408
+ private
291
409
 
292
410
  def is_human? picture
293
411
  model.can_program?(:ruby)
@@ -298,7 +416,7 @@ protected
298
416
  end
299
417
 
300
418
  def is_landscape? picture
301
- image = MiniMagick::Image.open(picture.path)
419
+ image = MiniMagick::Image.new(picture.path)
302
420
  image[:width] > image[:height]
303
421
  end
304
422
 
@@ -321,15 +439,34 @@ class MyUploader < CarrierWave::Uploader::Base
321
439
  process resize_to_fill: [280, 280]
322
440
  end
323
441
 
324
- version :small_thumb, :from_version => :thumb do
442
+ version :small_thumb, from_version: :thumb do
325
443
  process resize_to_fill: [20, 20]
326
444
  end
327
445
 
328
446
  end
329
447
  ```
330
448
 
331
- The option `:from_version` uses the file cached in the `:thumb` version instead
332
- 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.
333
470
 
334
471
  ## Making uploads work across form redisplays
335
472
 
@@ -340,7 +477,7 @@ file, just add a hidden field called `avatar_cache` (don't forget to add it to
340
477
  the attr_accessible list as necessary). In Rails, this would look like this:
341
478
 
342
479
  ```erb
343
- <%= form_for @user, :html => {:multipart => true} do |f| %>
480
+ <%= form_for @user, html: { multipart: true } do |f| %>
344
481
  <p>
345
482
  <label>My Avatar</label>
346
483
  <%= f.file_field :avatar %>
@@ -353,7 +490,7 @@ It might be a good idea to show the user that a file has been uploaded, in the
353
490
  case of images, a small thumbnail would be a good indicator:
354
491
 
355
492
  ```erb
356
- <%= form_for @user, :html => {:multipart => true} do |f| %>
493
+ <%= form_for @user, html: { multipart: true } do |f| %>
357
494
  <p>
358
495
  <label>My Avatar</label>
359
496
  <%= image_tag(@user.avatar_url) if @user.avatar? %>
@@ -369,7 +506,7 @@ If you want to remove a previously uploaded file on a mounted uploader, you can
369
506
  easily add a checkbox to the form which will remove the file when checked.
370
507
 
371
508
  ```erb
372
- <%= form_for @user, :html => {:multipart => true} do |f| %>
509
+ <%= form_for @user, html: { multipart: true } do |f| %>
373
510
  <p>
374
511
  <label>My Avatar</label>
375
512
  <%= image_tag(@user.avatar_url) if @user.avatar? %>
@@ -400,7 +537,7 @@ via a URL. CarrierWave makes this simple, just add the appropriate attribute to
400
537
  form and you're good to go:
401
538
 
402
539
  ```erb
403
- <%= form_for @user, :html => {:multipart => true} do |f| %>
540
+ <%= form_for @user, html: { multipart: true } do |f| %>
404
541
  <p>
405
542
  <label>My Avatar URL:</label>
406
543
  <%= image_tag(@user.avatar_url) if @user.avatar? %>
@@ -414,6 +551,17 @@ failures automatically with attribute validation errors. If you aren't, or you
414
551
  disable CarrierWave's `validate_download` option, you'll need to handle those
415
552
  errors yourself.
416
553
 
554
+ ### Retry option for download from remote location
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.
556
+ This option is effective when the remote destination is unstable.
557
+
558
+ ```rb
559
+ CarrierWave.configure do |config|
560
+ config.download_retry_count = 3 # Default 0
561
+ config.download_retry_wait_time = 3 # Default 5
562
+ end
563
+ ```
564
+
417
565
  ## Providing a default URL
418
566
 
419
567
  In many cases, especially when working with images, it might be a good idea to
@@ -422,7 +570,7 @@ this easily by overriding the `default_url` method in your uploader:
422
570
 
423
571
  ```ruby
424
572
  class MyUploader < CarrierWave::Uploader::Base
425
- def default_url
573
+ def default_url(*args)
426
574
  "/images/fallback/" + [version_name, "default.png"].compact.join('_')
427
575
  end
428
576
  end
@@ -432,7 +580,7 @@ Or if you are using the Rails asset pipeline:
432
580
 
433
581
  ```ruby
434
582
  class MyUploader < CarrierWave::Uploader::Base
435
- def default_url
583
+ def default_url(*args)
436
584
  ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
437
585
  end
438
586
  end
@@ -459,7 +607,7 @@ instance.recreate_versions!(:thumb, :large)
459
607
  Or on a mounted uploader:
460
608
 
461
609
  ```ruby
462
- User.all.each do |user|
610
+ User.find_each do |user|
463
611
  user.avatar.recreate_versions!
464
612
  end
465
613
  ```
@@ -467,7 +615,7 @@ end
467
615
  Note: `recreate_versions!` will throw an exception on records without an image. To avoid this, scope the records to those with images or check if an image exists within the block. If you're using ActiveRecord, recreating versions for a user avatar might look like this:
468
616
 
469
617
  ```ruby
470
- User.all.each do |user|
618
+ User.find_each do |user|
471
619
  user.avatar.recreate_versions! if user.avatar?
472
620
  end
473
621
  ```
@@ -497,6 +645,16 @@ If you're using Rails, create an initializer for this:
497
645
 
498
646
  config/initializers/carrierwave.rb
499
647
 
648
+ If you want CarrierWave to fail noisily in development, you can change these configs in your environment file:
649
+
650
+ ```ruby
651
+ CarrierWave.configure do |config|
652
+ config.ignore_integrity_errors = false
653
+ config.ignore_processing_errors = false
654
+ config.ignore_download_errors = false
655
+ end
656
+ ```
657
+
500
658
 
501
659
  ## Testing with CarrierWave
502
660
 
@@ -527,35 +685,43 @@ require 'carrierwave/test/matchers'
527
685
  describe MyUploader do
528
686
  include CarrierWave::Test::Matchers
529
687
 
688
+ let(:user) { double('user') }
689
+ let(:uploader) { MyUploader.new(user, :avatar) }
690
+
530
691
  before do
531
692
  MyUploader.enable_processing = true
532
- @uploader = MyUploader.new(@user, :avatar)
533
- @uploader.store!(File.open(path_to_file))
693
+ File.open(path_to_file) { |f| uploader.store!(f) }
534
694
  end
535
695
 
536
696
  after do
537
697
  MyUploader.enable_processing = false
538
- @uploader.remove!
698
+ uploader.remove!
539
699
  end
540
700
 
541
701
  context 'the thumb version' do
542
- it "should scale down a landscape image to be exactly 64 by 64 pixels" do
543
- @uploader.thumb.should have_dimensions(64, 64)
702
+ it "scales down a landscape image to be exactly 64 by 64 pixels" do
703
+ expect(uploader.thumb).to have_dimensions(64, 64)
544
704
  end
545
705
  end
546
706
 
547
707
  context 'the small version' do
548
- it "should scale down a landscape image to fit within 200 by 200 pixels" do
549
- @uploader.small.should be_no_larger_than(200, 200)
708
+ it "scales down a landscape image to fit within 200 by 200 pixels" do
709
+ expect(uploader.small).to be_no_larger_than(200, 200)
550
710
  end
551
711
  end
552
712
 
553
- it "should make the image readable only to the owner and not executable" do
554
- @uploader.should have_permissions(0600)
713
+ it "makes the image readable only to the owner and not executable" do
714
+ expect(uploader).to have_permissions(0600)
715
+ end
716
+
717
+ it "has the correct format" do
718
+ expect(uploader).to be_format('png')
555
719
  end
556
720
  end
557
721
  ```
558
722
 
723
+ If you're looking for minitest asserts, checkout [carrierwave_asserts](https://github.com/hcfairbanks/carrierwave_asserts).
724
+
559
725
  Setting the enable_processing flag on an uploader will prevent any of the versions from processing as well.
560
726
  Processing can be enabled for a single version by setting the processing flag on the version like so:
561
727
 
@@ -563,31 +729,44 @@ Processing can be enabled for a single version by setting the processing flag on
563
729
  @uploader.thumb.enable_processing = true
564
730
  ```
565
731
 
732
+ ## Fog
733
+
734
+ If you want to use fog you must add in your CarrierWave initializer the
735
+ following lines
736
+
737
+ ```ruby
738
+ config.fog_credentials = { ... } # Provider specific credentials
739
+ ```
740
+
566
741
  ## Using Amazon S3
567
742
 
568
- [Fog](http://github.com/fog/fog) is used to support Amazon S3. Ensure you have it in your Gemfile:
743
+ [Fog AWS](http://github.com/fog/fog-aws) is used to support Amazon S3. Ensure you have it in your Gemfile:
569
744
 
570
745
  ```ruby
571
- gem "fog", "~> 1.3.1"
746
+ gem "fog-aws"
572
747
  ```
573
748
 
574
749
  You'll need to provide your fog_credentials and a fog_directory (also known as a bucket) in an initializer.
575
- For the sake of performance it is assumed that the directory already exists, so please create it if need be.
750
+ For the sake of performance it is assumed that the directory already exists, so please create it if it needs to be.
576
751
  You can also pass in additional options, as documented fully in lib/carrierwave/storage/fog.rb. Here's a full example:
577
752
 
578
753
  ```ruby
579
754
  CarrierWave.configure do |config|
580
755
  config.fog_credentials = {
581
- :provider => 'AWS', # required
582
- :aws_access_key_id => 'xxx', # required
583
- :aws_secret_access_key => 'yyy', # required
584
- :region => 'eu-west-1', # optional, defaults to 'us-east-1'
585
- :host => 's3.example.com', # optional, defaults to nil
586
- :endpoint => 'https://s3.example.com:8080' # optional, defaults to nil
756
+ provider: 'AWS', # required
757
+ aws_access_key_id: 'xxx', # required unless using use_iam_profile
758
+ aws_secret_access_key: 'yyy', # required unless using use_iam_profile
759
+ use_iam_profile: true, # optional, defaults to false
760
+ region: 'eu-west-1', # optional, defaults to 'us-east-1'
761
+ host: 's3.example.com', # optional, defaults to nil
762
+ endpoint: 'https://s3.example.com:8080' # optional, defaults to nil
587
763
  }
588
- config.fog_directory = 'name_of_directory' # required
589
- config.fog_public = false # optional, defaults to true
590
- config.fog_attributes = {'Cache-Control'=>'max-age=315576000'} # optional, defaults to {}
764
+ config.fog_directory = 'name_of_bucket' # required
765
+ config.fog_public = false # optional, defaults to true
766
+ config.fog_attributes = { cache_control: "public, max-age=#{365.days.to_i}" } # optional, defaults to {}
767
+ # For an application which utilizes multiple servers but does not need caches persisted across requests,
768
+ # uncomment the line :file instead of the default :storage. Otherwise, it will use AWS as the temp cache store.
769
+ # config.cache_storage = :file
591
770
  end
592
771
  ```
593
772
 
@@ -601,6 +780,14 @@ end
601
780
 
602
781
  That's it! You can still use the `CarrierWave::Uploader#url` method to return the url to the file on Amazon S3.
603
782
 
783
+ **Note**: for Carrierwave to work properly it needs credentials with the following permissions:
784
+
785
+ * `s3:ListBucket`
786
+ * `s3:PutObject`
787
+ * `s3:GetObject`
788
+ * `s3:DeleteObject`
789
+ * `s3:PutObjectAcl`
790
+
604
791
  ## Using Rackspace Cloud Files
605
792
 
606
793
  [Fog](http://github.com/fog/fog) is used to support Rackspace Cloud Files. Ensure you have it in your Gemfile:
@@ -617,10 +804,10 @@ Using a US-based account:
617
804
  ```ruby
618
805
  CarrierWave.configure do |config|
619
806
  config.fog_credentials = {
620
- :provider => 'Rackspace',
621
- :rackspace_username => 'xxxxxx',
622
- :rackspace_api_key => 'yyyyyy',
623
- :rackspace_region => :ord # optional, defaults to :dfw
807
+ provider: 'Rackspace',
808
+ rackspace_username: 'xxxxxx',
809
+ rackspace_api_key: 'yyyyyy',
810
+ rackspace_region: :ord # optional, defaults to :dfw
624
811
  }
625
812
  config.fog_directory = 'name_of_directory'
626
813
  end
@@ -631,11 +818,11 @@ Using a UK-based account:
631
818
  ```ruby
632
819
  CarrierWave.configure do |config|
633
820
  config.fog_credentials = {
634
- :provider => 'Rackspace',
635
- :rackspace_username => 'xxxxxx',
636
- :rackspace_api_key => 'yyyyyy',
637
- :rackspace_auth_url => Fog::Rackspace::UK_AUTH_ENDPOINT,
638
- :rackspace_region => :lon
821
+ provider: 'Rackspace',
822
+ rackspace_username: 'xxxxxx',
823
+ rackspace_api_key: 'yyyyyy',
824
+ rackspace_auth_url: Fog::Rackspace::UK_AUTH_ENDPOINT,
825
+ rackspace_region: :lon
639
826
  }
640
827
  config.fog_directory = 'name_of_directory'
641
828
  end
@@ -660,29 +847,41 @@ end
660
847
  That's it! You can still use the `CarrierWave::Uploader#url` method to return
661
848
  the url to the file on Rackspace Cloud Files.
662
849
 
663
- ## Using Google Storage for Developers
850
+ ## Using Google Cloud Storage
664
851
 
665
- [Fog](http://github.com/fog/fog) is used to support Google Storage for Developers. Ensure you have it in your Gemfile:
852
+ [Fog](http://github.com/fog/fog-google) is used to support Google Cloud Storage. Ensure you have it in your Gemfile:
666
853
 
667
854
  ```ruby
668
- gem "fog"
855
+ gem "fog-google"
669
856
  ```
670
857
 
671
- You'll need to configure a directory (also known as a bucket), access key id and secret access key in the initializer.
858
+ You'll need to configure a directory (also known as a bucket) and the credentials in the initializer.
672
859
  For the sake of performance it is assumed that the directory already exists, so please create it if need be.
673
860
 
674
- Sign up [here](http://gs-signup-redirect.appspot.com/) and get your credentials [here](https://storage.cloud.google.com/m)
675
- under the section “Interoperable Access”.
861
+ Please read the [fog-google README](https://github.com/fog/fog-google/blob/master/README.md) on how to get credentials.
676
862
 
863
+ For Google Storage JSON API (recommended):
864
+ ```ruby
865
+ CarrierWave.configure do |config|
866
+ config.fog_credentials = {
867
+ provider: 'Google',
868
+ google_project: 'my-project',
869
+ google_json_key_string: 'xxxxxx'
870
+ # or use google_json_key_location if using an actual file
871
+ }
872
+ config.fog_directory = 'google_cloud_storage_bucket_name'
873
+ end
874
+ ```
677
875
 
876
+ For Google Storage XML API:
678
877
  ```ruby
679
878
  CarrierWave.configure do |config|
680
- config.fog_credentials = {
681
- :provider => 'Google',
682
- :google_storage_access_key_id => 'xxxxxx',
683
- :google_storage_secret_access_key => 'yyyyyy'
684
- }
685
- config.fog_directory = 'name_of_directory'
879
+ config.fog_credentials = {
880
+ provider: 'Google',
881
+ google_storage_access_key_id: 'xxxxxx',
882
+ google_storage_secret_access_key: 'yyyyyy'
883
+ }
884
+ config.fog_directory = 'google_cloud_storage_bucket_name'
686
885
  end
687
886
  ```
688
887
 
@@ -697,6 +896,31 @@ end
697
896
  That's it! You can still use the `CarrierWave::Uploader#url` method to return
698
897
  the url to the file on Google.
699
898
 
899
+ ## Optimized Loading of Fog
900
+
901
+ Since Carrierwave doesn't know which parts of Fog you intend to use, it will just load the entire library (unless you use e.g. [`fog-aws`, `fog-google`] instead of fog proper). If you prefer to load fewer classes into your application, you need to load those parts of Fog yourself *before* loading CarrierWave in your Gemfile. Ex:
902
+
903
+ ```ruby
904
+ gem "fog", "~> 1.27", require: "fog/rackspace/storage"
905
+ gem "carrierwave"
906
+ ```
907
+
908
+ A couple of notes about versions:
909
+ * This functionality was introduced in Fog v1.20.
910
+ * This functionality is slated for CarrierWave v1.0.0.
911
+
912
+ If you're not relying on Gemfile entries alone and are requiring "carrierwave" anywhere, ensure you require "fog/rackspace/storage" before it. Ex:
913
+
914
+ ```ruby
915
+ require "fog/rackspace/storage"
916
+ require "carrierwave"
917
+ ```
918
+
919
+ Beware that this specific require is only needed when working with a fog provider that was not extracted to its own gem yet.
920
+ A list of the extracted providers can be found in the page of the `fog` organizations [here](https://github.com/fog).
921
+
922
+ When in doubt, inspect `Fog.constants` to see what has been loaded.
923
+
700
924
  ## Dynamic Asset Host
701
925
 
702
926
  The `asset_host` config property can be assigned a proc (or anything that responds to `call`) for generating the host dynamically. The proc-compliant object gets an instance of the current `CarrierWave::Storage::Fog::File` or `CarrierWave::SanitizedFile` as its only argument.
@@ -710,67 +934,81 @@ CarrierWave.configure do |config|
710
934
  end
711
935
  ```
712
936
 
713
- ## Using RMagick
937
+ ## Manipulating images
714
938
 
715
939
  If you're uploading images, you'll probably want to manipulate them in some way,
716
- you might want to create thumbnail images for example. CarrierWave comes with a
717
- small library to make manipulating images with RMagick easier, you'll need to
718
- include it in your Uploader:
940
+ you might want to create thumbnail images for example.
719
941
 
720
- ```ruby
721
- class AvatarUploader < CarrierWave::Uploader::Base
722
- include CarrierWave::RMagick
723
- 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
724
956
  ```
725
957
 
726
- The RMagick module gives you a few methods, like
727
- `CarrierWave::RMagick#resize_to_fill` which manipulate the image file in some
728
- way. You can set a `process` callback, which will call that method any time a
729
- file is uploaded.
730
- There is a demonstration of convert here.
731
- 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.
732
964
 
733
965
  ```ruby
734
966
  class AvatarUploader < CarrierWave::Uploader::Base
735
- include CarrierWave::RMagick
736
-
737
- process :resize_to_fill => [200, 200]
738
- process :convert => 'png'
967
+ include CarrierWave::MiniMagick
739
968
 
740
- def filename
741
- super.chomp(File.extname(super)) + '.png' if original_filename.present?
742
- end
969
+ process resize_to_fill: [200, 200]
743
970
  end
744
971
  ```
745
972
 
746
- Check out the manipulate! method, which makes it easy for you to write your own
747
- manipulation methods.
748
-
749
- ## Using MiniMagick
973
+ #### List of available processing methods:
750
974
 
751
- MiniMagick is similar to RMagick but performs all the operations using the 'mogrify'
752
- command which is part of the standard ImageMagick kit. This allows you to have the power
753
- 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.
754
980
 
755
- See the MiniMagick site for more details:
981
+ See `carrierwave/processing/mini_magick.rb` for details.
756
982
 
757
- https://github.com/minimagick/minimagick
983
+ ### Using RMagick
758
984
 
759
- And the ImageMagick command line options for more for whats 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:
760
987
 
761
- http://www.imagemagick.org/script/command-line-options.php
988
+ ```ruby
989
+ class AvatarUploader < CarrierWave::Uploader::Base
990
+ include CarrierWave::RMagick
991
+ end
992
+ ```
762
993
 
763
- Currently, the MiniMagick carrierwave processor provides exactly the same methods as
764
- 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.
765
999
 
766
1000
  ```ruby
767
1001
  class AvatarUploader < CarrierWave::Uploader::Base
768
- include CarrierWave::MiniMagick
1002
+ include CarrierWave::RMagick
769
1003
 
770
- process :resize_to_fill => [200, 200]
1004
+ process resize_to_fill: [200, 200]
1005
+ process convert: 'png'
771
1006
  end
772
1007
  ```
773
1008
 
1009
+ Check out the manipulate! method, which makes it easy for you to write your own
1010
+ manipulation methods.
1011
+
774
1012
  ## Migrating from Paperclip
775
1013
 
776
1014
  If you are using Paperclip, you can use the provided compatibility module:
@@ -787,28 +1025,36 @@ details.
787
1025
  Be sure to use mount_on to specify the correct column:
788
1026
 
789
1027
  ```ruby
790
- mount_uploader :avatar, AvatarUploader, :mount_on => :avatar_file_name
1028
+ mount_uploader :avatar, AvatarUploader, mount_on: :avatar_file_name
791
1029
  ```
792
1030
 
793
- Unfortunately attachment_fu differs too much in philosophy for there to be a
794
- sensible compatibility mode. Patches for migrating from other solutions will be
795
- happily accepted.
796
-
797
- ## i18n
1031
+ ## I18n
798
1032
 
799
- The Active Record validations use the Rails i18n framework. Add these keys to
1033
+ The Active Record validations use the Rails `i18n` framework. Add these keys to
800
1034
  your translations file:
801
1035
 
802
1036
  ```yaml
803
1037
  errors:
804
1038
  messages:
805
- carrierwave_processing_error: "Cannot resize image."
806
- carrierwave_integrity_error: "Not an image."
807
- carrierwave_download_error: "Couldn't download image."
808
- extension_white_list_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}"
809
- extension_black_list_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
1039
+ carrierwave_processing_error: failed to be processed
1040
+ carrierwave_integrity_error: is not of an allowed file type
1041
+ carrierwave_download_error: could not be downloaded
1042
+ extension_allowlist_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}"
1043
+ extension_denylist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
1044
+ content_type_allowlist_error: "You are not allowed to upload %{content_type} files, allowed types: %{allowed_types}"
1045
+ content_type_denylist_error: "You are not allowed to upload %{content_type} files"
1046
+ processing_error: "Failed to manipulate, maybe it is not an image?"
1047
+ min_size_error: "File size should be greater than %{min_size}"
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"
810
1053
  ```
811
1054
 
1055
+ The [`carrierwave-i18n`](https://github.com/carrierwaveuploader/carrierwave-i18n)
1056
+ library adds support for additional locales.
1057
+
812
1058
  ## Large files
813
1059
 
814
1060
  By default, CarrierWave copies an uploaded file twice, first copying the file into the cache, then
@@ -822,6 +1068,7 @@ class MyUploader < CarrierWave::Uploader::Base
822
1068
  def move_to_cache
823
1069
  true
824
1070
  end
1071
+
825
1072
  def move_to_store
826
1073
  true
827
1074
  end
@@ -846,11 +1093,12 @@ end
846
1093
  Will add these callbacks:
847
1094
 
848
1095
  ```ruby
849
- after_save :store_avatar!
850
1096
  before_save :write_avatar_identifier
851
- after_commit :remove_avatar! :on => :destroy
852
- before_update :store_previous_model_for_avatar
853
- after_save :remove_previously_stored_avatar
1097
+ after_save :store_previous_changes_for_avatar
1098
+ after_commit :remove_avatar!, on: :destroy
1099
+ after_commit :mark_remove_avatar_false, on: :update
1100
+ after_commit :remove_previously_stored_avatar, on: :update
1101
+ after_commit :store_avatar!, on: [:create, :update]
854
1102
  ```
855
1103
 
856
1104
  If you want to skip any of these callbacks (eg. you want to keep the existing
@@ -860,17 +1108,43 @@ avatar, even after uploading a new one), you can use ActiveRecord’s
860
1108
  ```ruby
861
1109
  class User
862
1110
  mount_uploader :avatar, AvatarUploader
863
- skip_callback :save, :after, :remove_previously_stored_avatar
1111
+ skip_callback :commit, :after, :remove_previously_stored_avatar
1112
+ end
1113
+ ```
1114
+
1115
+ ## Uploader Callbacks
1116
+
1117
+ In addition to the ActiveRecord callbacks described above, uploaders also have callbacks.
1118
+
1119
+ ```ruby
1120
+ class MyUploader < ::CarrierWave::Uploader::Base
1121
+ before :remove, :log_removal
1122
+ private
1123
+ def log_removal
1124
+ ::Rails.logger.info(format('Deleting file on S3: %s', @file))
1125
+ end
864
1126
  end
865
1127
  ```
866
1128
 
1129
+ Uploader callbacks can be `before` or `after` the following events:
1130
+
1131
+ ```
1132
+ cache
1133
+ process
1134
+ remove
1135
+ retrieve_from_cache
1136
+ store
1137
+ ```
1138
+
867
1139
  ## Contributing to CarrierWave
868
1140
 
869
1141
  See [CONTRIBUTING.md](https://github.com/carrierwaveuploader/carrierwave/blob/master/CONTRIBUTING.md)
870
1142
 
871
1143
  ## License
872
1144
 
873
- Copyright (c) 2008-2013 Jonas Nicklas
1145
+ The MIT License (MIT)
1146
+
1147
+ Copyright (c) 2008 Jonas Nicklas
874
1148
 
875
1149
  Permission is hereby granted, free of charge, to any person obtaining
876
1150
  a copy of this software and associated documentation files (the