carrierwave 0.9.0 → 3.0.2

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 (56) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +508 -158
  3. data/lib/carrierwave/compatibility/paperclip.rb +31 -21
  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 +220 -187
  9. data/lib/carrierwave/mounter.rb +255 -0
  10. data/lib/carrierwave/orm/activerecord.rb +24 -34
  11. data/lib/carrierwave/processing/mini_magick.rb +142 -79
  12. data/lib/carrierwave/processing/rmagick.rb +76 -35
  13. data/lib/carrierwave/processing/vips.rb +284 -0
  14. data/lib/carrierwave/processing.rb +1 -1
  15. data/lib/carrierwave/sanitized_file.rb +89 -70
  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 -58
  19. data/lib/carrierwave/storage.rb +1 -7
  20. data/lib/carrierwave/test/matchers.rb +88 -19
  21. data/lib/carrierwave/uploader/cache.rb +88 -44
  22. data/lib/carrierwave/uploader/callbacks.rb +1 -3
  23. data/lib/carrierwave/uploader/configuration.rb +81 -9
  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 +5 -69
  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 +54 -21
  34. data/lib/carrierwave/uploader/proxy.rb +30 -8
  35. data/lib/carrierwave/uploader/remove.rb +0 -2
  36. data/lib/carrierwave/uploader/serialization.rb +3 -5
  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 +173 -124
  40. data/lib/carrierwave/uploader.rb +12 -6
  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 +2 -3
  44. data/lib/carrierwave/validations/active_model.rb +7 -13
  45. data/lib/carrierwave/version.rb +1 -1
  46. data/lib/carrierwave.rb +41 -16
  47. data/lib/generators/templates/{uploader.rb → uploader.rb.erb} +5 -9
  48. data/lib/generators/uploader_generator.rb +3 -3
  49. metadata +224 -100
  50. data/lib/carrierwave/locale/cs.yml +0 -11
  51. data/lib/carrierwave/locale/de.yml +0 -11
  52. data/lib/carrierwave/locale/nl.yml +0 -11
  53. data/lib/carrierwave/locale/sk.yml +0 -11
  54. data/lib/carrierwave/processing/mime_types.rb +0 -73
  55. data/lib/carrierwave/uploader/extension_blacklist.rb +0 -47
  56. data/lib/carrierwave/uploader/extension_whitelist.rb +0 -49
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://secure.travis-ci.org/carrierwaveuploader/carrierwave.png)](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,14 +110,22 @@ 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:
@@ -118,6 +136,77 @@ Other ORM support has been extracted into separate gems:
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,99 +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
 
164
- ### Filenames and unicode chars
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
165
269
 
166
- Another security issue you should care for is the file names (see
167
- [Ruby On Rails Security Guide](http://guides.rubyonrails.org/security.html#file-uploads)).
168
- By default, CarrierWave provides only English letters, arabic numerals and '-+_.' symbols as
169
- white-listed characters in the file name. If you want to support local scripts (Cyrillic letters, letters with diacritics and so on), you
170
- have to override `sanitize_regexp` method. It should return regular expression which would match
171
- all *non*-allowed symbols.
270
+ ```ruby
271
+ class MyUploader < CarrierWave::Uploader::Base
272
+ def content_type_allowlist
273
+ /image\//
274
+ end
275
+ end
276
+ ```
172
277
 
173
- With Ruby 1.9 and higher you can simply write (as it has [Oniguruma](http://oniguruma.rubyforge.org/oniguruma/)
174
- built-in):
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
175
280
 
176
281
  ```ruby
177
- CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/
282
+ class NoJsonUploader < CarrierWave::Uploader::Base
283
+ def content_type_denylist
284
+ ['application/text', 'application/json']
285
+ end
286
+ end
178
287
  ```
179
288
 
180
- With Ruby 1.8 you have to manually specify all character ranges. For example, for files which may
181
- contain Russian letters:
289
+ ### CVE-2016-3714 (ImageTragick)
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.
291
+
292
+
293
+ A valid allowlist that will restrict your uploader to images only, and mitigate the CVE is:
182
294
 
183
295
  ```ruby
184
- CarrierWave::SanitizedFile.sanitize_regexp = /[^a-zA-Zа-яА-ЯёЁ0-9\.\-\+_]/u
296
+ class MyUploader < CarrierWave::Uploader::Base
297
+ def content_type_allowlist
298
+ [/image\//]
299
+ end
300
+ end
185
301
  ```
186
302
 
187
- Also make sure that allowing non-latin characters won't cause a compatibility issue with a third-party
188
- plugins or client-side software.
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.
189
304
 
190
- ## Setting the content type
305
+ ### Filenames and unicode chars
191
306
 
192
- If you care about the content type of your files and notice that it's not being set
193
- as expected, you can configure your uploaders to use `CarrierWave::MimeTypes`.
194
- This adds a dependency on the [mime-types](http://rubygems.org/gems/mime-types) gem,
195
- but is recommended when using fog, and fog already has a dependency on mime-types.
307
+ Another security issue you should care for is the file names (see
308
+ [Ruby On Rails Security Guide](http://guides.rubyonrails.org/security.html#file-uploads)).
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
311
+ have to override `sanitize_regexp` method. It should return regular expression which would match
312
+ all *non*-allowed symbols.
196
313
 
197
314
  ```ruby
198
- require 'carrierwave/processing/mime_types'
315
+ CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/
316
+ ```
199
317
 
200
- class MyUploader < CarrierWave::Uploader::Base
201
- include CarrierWave::MimeTypes
318
+ Also make sure that allowing non-latin characters won't cause a compatibility issue with a third-party
319
+ plugins or client-side software.
202
320
 
203
- process :set_content_type
204
- end
205
- ```
321
+ ## Setting the content type
322
+
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.
206
325
 
207
326
  ## Adding versions
208
327
 
209
- Often you'll want to add different versions of the same file. The classic
210
- example is image thumbnails. There is built in support for this:
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).
211
330
 
212
331
  ```ruby
213
332
  class MyUploader < CarrierWave::Uploader::Base
214
- include CarrierWave::RMagick
333
+ include CarrierWave::MiniMagick
215
334
 
216
- process :resize_to_fit => [800, 800]
335
+ process resize_to_fit: [800, 800]
217
336
 
218
337
  version :thumb do
219
- process :resize_to_fill => [200,200]
338
+ process resize_to_fill: [200,200]
220
339
  end
221
340
 
222
341
  end
223
342
  ```
224
343
 
225
344
  When this uploader is used, an uploaded image would be scaled to be no larger
226
- than 800 by 800 pixels. A version called thumb is then created, which is scaled
227
- 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:
228
353
 
229
354
  ```ruby
230
355
  uploader = AvatarUploader.new
231
356
  uploader.store!(my_file) # size: 1024x768
232
357
 
233
- uploader.url # => '/url/to/my_file.png' # size: 800x600
358
+ uploader.url # => '/url/to/my_file.png' # size: 800x800
234
359
  uploader.thumb.url # => '/url/to/thumb_my_file.png' # size: 200x200
235
360
  ```
236
361
 
237
362
  One important thing to remember is that process is called *before* versions are
238
363
  created. This can cut down on processing cost.
239
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
+
240
383
  It is possible to nest versions within versions:
241
384
 
242
385
  ```ruby
@@ -258,11 +401,11 @@ properties within the model or based on the picture itself.
258
401
  ```ruby
259
402
  class MyUploader < CarrierWave::Uploader::Base
260
403
 
261
- version :human, :if => :is_human?
262
- version :monkey, :if => :is_monkey?
263
- version :banner, :if => :is_landscape?
404
+ version :human, if: :is_human?
405
+ version :monkey, if: :is_monkey?
406
+ version :banner, if: :is_landscape?
264
407
 
265
- protected
408
+ private
266
409
 
267
410
  def is_human? picture
268
411
  model.can_program?(:ruby)
@@ -273,7 +416,7 @@ protected
273
416
  end
274
417
 
275
418
  def is_landscape? picture
276
- image = MiniMagick::Image.open(picture.path)
419
+ image = MiniMagick::Image.new(picture.path)
277
420
  image[:width] > image[:height]
278
421
  end
279
422
 
@@ -296,15 +439,34 @@ class MyUploader < CarrierWave::Uploader::Base
296
439
  process resize_to_fill: [280, 280]
297
440
  end
298
441
 
299
- version :small_thumb, :from_version => :thumb do
442
+ version :small_thumb, from_version: :thumb do
300
443
  process resize_to_fill: [20, 20]
301
444
  end
302
445
 
303
446
  end
304
447
  ```
305
448
 
306
- The option `:from_version` uses the file cached in the `:thumb` version instead
307
- 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.
308
470
 
309
471
  ## Making uploads work across form redisplays
310
472
 
@@ -315,7 +477,7 @@ file, just add a hidden field called `avatar_cache` (don't forget to add it to
315
477
  the attr_accessible list as necessary). In Rails, this would look like this:
316
478
 
317
479
  ```erb
318
- <%= form_for @user, :html => {:multipart => true} do |f| %>
480
+ <%= form_for @user, html: { multipart: true } do |f| %>
319
481
  <p>
320
482
  <label>My Avatar</label>
321
483
  <%= f.file_field :avatar %>
@@ -328,7 +490,7 @@ It might be a good idea to show the user that a file has been uploaded, in the
328
490
  case of images, a small thumbnail would be a good indicator:
329
491
 
330
492
  ```erb
331
- <%= form_for @user, :html => {:multipart => true} do |f| %>
493
+ <%= form_for @user, html: { multipart: true } do |f| %>
332
494
  <p>
333
495
  <label>My Avatar</label>
334
496
  <%= image_tag(@user.avatar_url) if @user.avatar? %>
@@ -344,7 +506,7 @@ If you want to remove a previously uploaded file on a mounted uploader, you can
344
506
  easily add a checkbox to the form which will remove the file when checked.
345
507
 
346
508
  ```erb
347
- <%= form_for @user, :html => {:multipart => true} do |f| %>
509
+ <%= form_for @user, html: { multipart: true } do |f| %>
348
510
  <p>
349
511
  <label>My Avatar</label>
350
512
  <%= image_tag(@user.avatar_url) if @user.avatar? %>
@@ -360,7 +522,13 @@ easily add a checkbox to the form which will remove the file when checked.
360
522
  <% end %>
361
523
  ```
362
524
 
363
- If you want to remove the file manually, you can call <code>remove_avatar!</code>.
525
+ If you want to remove the file manually, you can call <code>remove_avatar!</code>, then save the object.
526
+
527
+ ```erb
528
+ @user.remove_avatar!
529
+ @user.save
530
+ #=> true
531
+ ```
364
532
 
365
533
  ## Uploading files from a remote location
366
534
 
@@ -369,7 +537,7 @@ via a URL. CarrierWave makes this simple, just add the appropriate attribute to
369
537
  form and you're good to go:
370
538
 
371
539
  ```erb
372
- <%= form_for @user, :html => {:multipart => true} do |f| %>
540
+ <%= form_for @user, html: { multipart: true } do |f| %>
373
541
  <p>
374
542
  <label>My Avatar URL:</label>
375
543
  <%= image_tag(@user.avatar_url) if @user.avatar? %>
@@ -383,6 +551,17 @@ failures automatically with attribute validation errors. If you aren't, or you
383
551
  disable CarrierWave's `validate_download` option, you'll need to handle those
384
552
  errors yourself.
385
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
+
386
565
  ## Providing a default URL
387
566
 
388
567
  In many cases, especially when working with images, it might be a good idea to
@@ -391,7 +570,7 @@ this easily by overriding the `default_url` method in your uploader:
391
570
 
392
571
  ```ruby
393
572
  class MyUploader < CarrierWave::Uploader::Base
394
- def default_url
573
+ def default_url(*args)
395
574
  "/images/fallback/" + [version_name, "default.png"].compact.join('_')
396
575
  end
397
576
  end
@@ -401,7 +580,7 @@ Or if you are using the Rails asset pipeline:
401
580
 
402
581
  ```ruby
403
582
  class MyUploader < CarrierWave::Uploader::Base
404
- def default_url
583
+ def default_url(*args)
405
584
  ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
406
585
  end
407
586
  end
@@ -428,11 +607,19 @@ instance.recreate_versions!(:thumb, :large)
428
607
  Or on a mounted uploader:
429
608
 
430
609
  ```ruby
431
- User.all.each do |user|
610
+ User.find_each do |user|
432
611
  user.avatar.recreate_versions!
433
612
  end
434
613
  ```
435
614
 
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:
616
+
617
+ ```ruby
618
+ User.find_each do |user|
619
+ user.avatar.recreate_versions! if user.avatar?
620
+ end
621
+ ```
622
+
436
623
  ## Configuring CarrierWave
437
624
 
438
625
  CarrierWave has a broad range of configuration options, which you can configure,
@@ -458,6 +645,16 @@ If you're using Rails, create an initializer for this:
458
645
 
459
646
  config/initializers/carrierwave.rb
460
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
+
461
658
 
462
659
  ## Testing with CarrierWave
463
660
 
@@ -474,6 +671,9 @@ if Rails.env.test? or Rails.env.cucumber?
474
671
  end
475
672
  ```
476
673
 
674
+ Remember, if you have already set `storage :something` in your uploader, the `storage`
675
+ setting from this initializer will be ignored.
676
+
477
677
  If you need to test your processing, you should test it in isolation, and enable
478
678
  processing only for those tests that need it.
479
679
 
@@ -485,35 +685,43 @@ require 'carrierwave/test/matchers'
485
685
  describe MyUploader do
486
686
  include CarrierWave::Test::Matchers
487
687
 
688
+ let(:user) { double('user') }
689
+ let(:uploader) { MyUploader.new(user, :avatar) }
690
+
488
691
  before do
489
692
  MyUploader.enable_processing = true
490
- @uploader = MyUploader.new(@user, :avatar)
491
- @uploader.store!(File.open(path_to_file))
693
+ File.open(path_to_file) { |f| uploader.store!(f) }
492
694
  end
493
695
 
494
696
  after do
495
697
  MyUploader.enable_processing = false
496
- @uploader.remove!
698
+ uploader.remove!
497
699
  end
498
700
 
499
701
  context 'the thumb version' do
500
- it "should scale down a landscape image to be exactly 64 by 64 pixels" do
501
- @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)
502
704
  end
503
705
  end
504
706
 
505
707
  context 'the small version' do
506
- it "should scale down a landscape image to fit within 200 by 200 pixels" do
507
- @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)
508
710
  end
509
711
  end
510
712
 
511
- it "should make the image readable only to the owner and not executable" do
512
- @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')
513
719
  end
514
720
  end
515
721
  ```
516
722
 
723
+ If you're looking for minitest asserts, checkout [carrierwave_asserts](https://github.com/hcfairbanks/carrierwave_asserts).
724
+
517
725
  Setting the enable_processing flag on an uploader will prevent any of the versions from processing as well.
518
726
  Processing can be enabled for a single version by setting the processing flag on the version like so:
519
727
 
@@ -521,31 +729,44 @@ Processing can be enabled for a single version by setting the processing flag on
521
729
  @uploader.thumb.enable_processing = true
522
730
  ```
523
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
+
524
741
  ## Using Amazon S3
525
742
 
526
- [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:
527
744
 
528
745
  ```ruby
529
- gem "fog", "~> 1.3.1"
746
+ gem "fog-aws"
530
747
  ```
531
748
 
532
749
  You'll need to provide your fog_credentials and a fog_directory (also known as a bucket) in an initializer.
533
- 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.
534
751
  You can also pass in additional options, as documented fully in lib/carrierwave/storage/fog.rb. Here's a full example:
535
752
 
536
753
  ```ruby
537
754
  CarrierWave.configure do |config|
538
755
  config.fog_credentials = {
539
- :provider => 'AWS', # required
540
- :aws_access_key_id => 'xxx', # required
541
- :aws_secret_access_key => 'yyy', # required
542
- :region => 'eu-west-1', # optional, defaults to 'us-east-1'
543
- :host => 's3.example.com', # optional, defaults to nil
544
- :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
545
763
  }
546
- config.fog_directory = 'name_of_directory' # required
547
- config.fog_public = false # optional, defaults to true
548
- 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
549
770
  end
550
771
  ```
551
772
 
@@ -559,12 +780,20 @@ end
559
780
 
560
781
  That's it! You can still use the `CarrierWave::Uploader#url` method to return the url to the file on Amazon S3.
561
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
+
562
791
  ## Using Rackspace Cloud Files
563
792
 
564
793
  [Fog](http://github.com/fog/fog) is used to support Rackspace Cloud Files. Ensure you have it in your Gemfile:
565
794
 
566
795
  ```ruby
567
- gem "fog", "~> 1.10.1"
796
+ gem "fog"
568
797
  ```
569
798
 
570
799
  You'll need to configure a directory (also known as a container), username and API key in the initializer.
@@ -575,10 +804,10 @@ Using a US-based account:
575
804
  ```ruby
576
805
  CarrierWave.configure do |config|
577
806
  config.fog_credentials = {
578
- :provider => 'Rackspace',
579
- :rackspace_username => 'xxxxxx',
580
- :rackspace_api_key => 'yyyyyy',
581
- :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
582
811
  }
583
812
  config.fog_directory = 'name_of_directory'
584
813
  end
@@ -589,11 +818,11 @@ Using a UK-based account:
589
818
  ```ruby
590
819
  CarrierWave.configure do |config|
591
820
  config.fog_credentials = {
592
- :provider => 'Rackspace',
593
- :rackspace_username => 'xxxxxx',
594
- :rackspace_api_key => 'yyyyyy',
595
- :rackspace_auth_url => Fog::Rackspace::UK_AUTH_ENDPOINT,
596
- :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
597
826
  }
598
827
  config.fog_directory = 'name_of_directory'
599
828
  end
@@ -618,29 +847,41 @@ end
618
847
  That's it! You can still use the `CarrierWave::Uploader#url` method to return
619
848
  the url to the file on Rackspace Cloud Files.
620
849
 
621
- ## Using Google Storage for Developers
850
+ ## Using Google Cloud Storage
622
851
 
623
- [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:
624
853
 
625
854
  ```ruby
626
- gem "fog", "~> 1.3.1"
855
+ gem "fog-google"
627
856
  ```
628
857
 
629
- 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.
630
859
  For the sake of performance it is assumed that the directory already exists, so please create it if need be.
631
860
 
632
- Sign up [here](http://gs-signup-redirect.appspot.com/) and get your credentials [here](https://storage.cloud.google.com/m)
633
- 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.
634
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
+ ```
635
875
 
876
+ For Google Storage XML API:
636
877
  ```ruby
637
878
  CarrierWave.configure do |config|
638
- config.fog_credentials = {
639
- :provider => 'Google',
640
- :google_storage_access_key_id => 'xxxxxx',
641
- :google_storage_secret_access_key => 'yyyyyy'
642
- }
643
- 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'
644
885
  end
645
886
  ```
646
887
 
@@ -655,6 +896,31 @@ end
655
896
  That's it! You can still use the `CarrierWave::Uploader#url` method to return
656
897
  the url to the file on Google.
657
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
+
658
924
  ## Dynamic Asset Host
659
925
 
660
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.
@@ -668,67 +934,81 @@ CarrierWave.configure do |config|
668
934
  end
669
935
  ```
670
936
 
671
- ## Using RMagick
937
+ ## Manipulating images
672
938
 
673
939
  If you're uploading images, you'll probably want to manipulate them in some way,
674
- you might want to create thumbnail images for example. CarrierWave comes with a
675
- small library to make manipulating images with RMagick easier, you'll need to
676
- include it in your Uploader:
940
+ you might want to create thumbnail images for example.
677
941
 
678
- ```ruby
679
- class AvatarUploader < CarrierWave::Uploader::Base
680
- include CarrierWave::RMagick
681
- 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
682
956
  ```
683
957
 
684
- The RMagick module gives you a few methods, like
685
- `CarrierWave::RMagick#resize_to_fill` which manipulate the image file in some
686
- way. You can set a `process` callback, which will call that method any time a
687
- file is uploaded.
688
- There is a demonstration of convert here.
689
- 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.
690
964
 
691
965
  ```ruby
692
966
  class AvatarUploader < CarrierWave::Uploader::Base
693
- include CarrierWave::RMagick
694
-
695
- process :resize_to_fill => [200, 200]
696
- process :convert => 'png'
967
+ include CarrierWave::MiniMagick
697
968
 
698
- def filename
699
- super.chomp(File.extname(super)) + '.png'
700
- end
969
+ process resize_to_fill: [200, 200]
701
970
  end
702
971
  ```
703
972
 
704
- Check out the manipulate! method, which makes it easy for you to write your own
705
- manipulation methods.
973
+ #### List of available processing methods:
706
974
 
707
- ## Using MiniMagick
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.
708
980
 
709
- MiniMagick is similar to RMagick but performs all the operations using the 'mogrify'
710
- command which is part of the standard ImageMagick kit. This allows you to have the power
711
- of ImageMagick without having to worry about installing all the RMagick libraries.
712
-
713
- See the MiniMagick site for more details:
981
+ See `carrierwave/processing/mini_magick.rb` for details.
714
982
 
715
- https://github.com/minimagick/minimagick
983
+ ### Using RMagick
716
984
 
717
- 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:
718
987
 
719
- http://www.imagemagick.org/script/command-line-options.php
988
+ ```ruby
989
+ class AvatarUploader < CarrierWave::Uploader::Base
990
+ include CarrierWave::RMagick
991
+ end
992
+ ```
720
993
 
721
- Currently, the MiniMagick carrierwave processor provides exactly the same methods as
722
- 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.
723
999
 
724
1000
  ```ruby
725
1001
  class AvatarUploader < CarrierWave::Uploader::Base
726
- include CarrierWave::MiniMagick
1002
+ include CarrierWave::RMagick
727
1003
 
728
- process :resize_to_fill => [200, 200]
1004
+ process resize_to_fill: [200, 200]
1005
+ process convert: 'png'
729
1006
  end
730
1007
  ```
731
1008
 
1009
+ Check out the manipulate! method, which makes it easy for you to write your own
1010
+ manipulation methods.
1011
+
732
1012
  ## Migrating from Paperclip
733
1013
 
734
1014
  If you are using Paperclip, you can use the provided compatibility module:
@@ -745,26 +1025,36 @@ details.
745
1025
  Be sure to use mount_on to specify the correct column:
746
1026
 
747
1027
  ```ruby
748
- mount_uploader :avatar, AvatarUploader, :mount_on => :avatar_file_name
1028
+ mount_uploader :avatar, AvatarUploader, mount_on: :avatar_file_name
749
1029
  ```
750
1030
 
751
- Unfortunately attachment_fu differs too much in philosophy for there to be a
752
- sensible compatibility mode. Patches for migrating from other solutions will be
753
- happily accepted.
754
-
755
- ## i18n
1031
+ ## I18n
756
1032
 
757
- 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
758
1034
  your translations file:
759
1035
 
760
1036
  ```yaml
761
1037
  errors:
762
1038
  messages:
763
- carrierwave_processing_error: "Cannot resize image."
764
- carrierwave_integrity_error: "Not an image."
765
- carrierwave_download_error: "Couldn't download image."
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"
766
1053
  ```
767
1054
 
1055
+ The [`carrierwave-i18n`](https://github.com/carrierwaveuploader/carrierwave-i18n)
1056
+ library adds support for additional locales.
1057
+
768
1058
  ## Large files
769
1059
 
770
1060
  By default, CarrierWave copies an uploaded file twice, first copying the file into the cache, then
@@ -778,6 +1068,7 @@ class MyUploader < CarrierWave::Uploader::Base
778
1068
  def move_to_cache
779
1069
  true
780
1070
  end
1071
+
781
1072
  def move_to_store
782
1073
  true
783
1074
  end
@@ -788,13 +1079,72 @@ When the `move_to_cache` and/or `move_to_store` methods return true, files will
788
1079
 
789
1080
  This has only been tested with the local filesystem store.
790
1081
 
1082
+ ## Skipping ActiveRecord callbacks
1083
+
1084
+ By default, mounting an uploader into an ActiveRecord model will add a few
1085
+ callbacks. For example, this code:
1086
+
1087
+ ```ruby
1088
+ class User
1089
+ mount_uploader :avatar, AvatarUploader
1090
+ end
1091
+ ```
1092
+
1093
+ Will add these callbacks:
1094
+
1095
+ ```ruby
1096
+ before_save :write_avatar_identifier
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]
1102
+ ```
1103
+
1104
+ If you want to skip any of these callbacks (eg. you want to keep the existing
1105
+ avatar, even after uploading a new one), you can use ActiveRecord’s
1106
+ `skip_callback` method.
1107
+
1108
+ ```ruby
1109
+ class User
1110
+ mount_uploader :avatar, AvatarUploader
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
1126
+ end
1127
+ ```
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
+
791
1139
  ## Contributing to CarrierWave
792
1140
 
793
1141
  See [CONTRIBUTING.md](https://github.com/carrierwaveuploader/carrierwave/blob/master/CONTRIBUTING.md)
794
1142
 
795
1143
  ## License
796
1144
 
797
- Copyright (c) 2008-2013 Jonas Nicklas
1145
+ The MIT License (MIT)
1146
+
1147
+ Copyright (c) 2008 Jonas Nicklas
798
1148
 
799
1149
  Permission is hereby granted, free of charge, to any person obtaining
800
1150
  a copy of this software and associated documentation files (the