carrierwave 0.11.2 → 3.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +495 -173
  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 +217 -182
  9. data/lib/carrierwave/mounter.rb +257 -0
  10. data/lib/carrierwave/orm/activerecord.rb +29 -35
  11. data/lib/carrierwave/processing/mini_magick.rb +169 -84
  12. data/lib/carrierwave/processing/rmagick.rb +107 -25
  13. data/lib/carrierwave/processing/vips.rb +315 -0
  14. data/lib/carrierwave/processing.rb +1 -1
  15. data/lib/carrierwave/sanitized_file.rb +105 -87
  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 +228 -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 +84 -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 +51 -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 +85 -28
  38. data/lib/carrierwave/uploader/url.rb +8 -7
  39. data/lib/carrierwave/uploader/versions.rb +175 -125
  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 +48 -21
  47. data/lib/generators/templates/{uploader.rb → uploader.rb.erb} +8 -11
  48. data/lib/generators/uploader_generator.rb +3 -3
  49. metadata +124 -86
  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,18 +645,31 @@ 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
 
503
661
  It's a good idea to test your uploaders in isolation. In order to speed up your
504
- tests, it's recommended to switch off processing in your tests, and to use the
505
- file storage. In Rails you could do that by adding an initializer with:
662
+ tests, it's recommended to switch off processing in your tests, and to use the file storage.
663
+ Also, you can disable SSRF protection at your own risk using the `skip_ssrf_protection` configuration.
664
+
665
+ In Rails you could do that by adding an initializer with:
506
666
 
507
667
  ```ruby
508
668
  if Rails.env.test? or Rails.env.cucumber?
509
669
  CarrierWave.configure do |config|
510
670
  config.storage = :file
511
671
  config.enable_processing = false
672
+ config.skip_ssrf_protection = true
512
673
  end
513
674
  end
514
675
  ```
@@ -527,35 +688,43 @@ require 'carrierwave/test/matchers'
527
688
  describe MyUploader do
528
689
  include CarrierWave::Test::Matchers
529
690
 
691
+ let(:user) { double('user') }
692
+ let(:uploader) { MyUploader.new(user, :avatar) }
693
+
530
694
  before do
531
695
  MyUploader.enable_processing = true
532
- @uploader = MyUploader.new(@user, :avatar)
533
- @uploader.store!(File.open(path_to_file))
696
+ File.open(path_to_file) { |f| uploader.store!(f) }
534
697
  end
535
698
 
536
699
  after do
537
700
  MyUploader.enable_processing = false
538
- @uploader.remove!
701
+ uploader.remove!
539
702
  end
540
703
 
541
704
  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)
705
+ it "scales down a landscape image to be exactly 64 by 64 pixels" do
706
+ expect(uploader.thumb).to have_dimensions(64, 64)
544
707
  end
545
708
  end
546
709
 
547
710
  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)
711
+ it "scales down a landscape image to fit within 200 by 200 pixels" do
712
+ expect(uploader.small).to be_no_larger_than(200, 200)
550
713
  end
551
714
  end
552
715
 
553
- it "should make the image readable only to the owner and not executable" do
554
- @uploader.should have_permissions(0600)
716
+ it "makes the image readable only to the owner and not executable" do
717
+ expect(uploader).to have_permissions(0600)
718
+ end
719
+
720
+ it "has the correct format" do
721
+ expect(uploader).to be_format('png')
555
722
  end
556
723
  end
557
724
  ```
558
725
 
726
+ If you're looking for minitest asserts, checkout [carrierwave_asserts](https://github.com/hcfairbanks/carrierwave_asserts).
727
+
559
728
  Setting the enable_processing flag on an uploader will prevent any of the versions from processing as well.
560
729
  Processing can be enabled for a single version by setting the processing flag on the version like so:
561
730
 
@@ -563,31 +732,48 @@ Processing can be enabled for a single version by setting the processing flag on
563
732
  @uploader.thumb.enable_processing = true
564
733
  ```
565
734
 
735
+ ## Fog
736
+
737
+ If you want to use fog you must add in your CarrierWave initializer the
738
+ following lines
739
+
740
+ ```ruby
741
+ config.fog_credentials = { ... } # Provider specific credentials
742
+ ```
743
+
566
744
  ## Using Amazon S3
567
745
 
568
- [Fog](http://github.com/fog/fog) is used to support Amazon S3. Ensure you have it in your Gemfile:
746
+ [Fog AWS](http://github.com/fog/fog-aws) is used to support Amazon S3. Ensure you have it in your Gemfile:
569
747
 
570
748
  ```ruby
571
- gem "fog", "~> 1.3.1"
749
+ gem "fog-aws"
572
750
  ```
573
751
 
574
752
  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.
753
+ For the sake of performance it is assumed that the directory already exists, so please create it if it needs to be.
576
754
  You can also pass in additional options, as documented fully in lib/carrierwave/storage/fog.rb. Here's a full example:
577
755
 
578
756
  ```ruby
579
757
  CarrierWave.configure do |config|
580
758
  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
759
+ provider: 'AWS', # required
760
+ aws_access_key_id: 'xxx', # required unless using use_iam_profile
761
+ aws_secret_access_key: 'yyy', # required unless using use_iam_profile
762
+ use_iam_profile: true, # optional, defaults to false
763
+ region: 'eu-west-1', # optional, defaults to 'us-east-1'
764
+ host: 's3.example.com', # optional, defaults to nil
765
+ endpoint: 'https://s3.example.com:8080' # optional, defaults to nil
587
766
  }
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 {}
767
+ config.fog_directory = 'name_of_bucket' # required
768
+ config.fog_public = false # optional, defaults to true
769
+ config.fog_attributes = { cache_control: "public, max-age=#{365.days.to_i}" } # optional, defaults to {}
770
+ # Use this if you have AWS S3 ACLs disabled.
771
+ # config.fog_attributes = { 'x-amz-acl' => 'bucket-owner-full-control' }
772
+ # Use this if you have Google Cloud Storage uniform bucket-level access enabled.
773
+ # config.fog_attributes = { uniform: true }
774
+ # For an application which utilizes multiple servers but does not need caches persisted across requests,
775
+ # uncomment the line :file instead of the default :storage. Otherwise, it will use AWS as the temp cache store.
776
+ # config.cache_storage = :file
591
777
  end
592
778
  ```
593
779
 
@@ -601,6 +787,14 @@ end
601
787
 
602
788
  That's it! You can still use the `CarrierWave::Uploader#url` method to return the url to the file on Amazon S3.
603
789
 
790
+ **Note**: for Carrierwave to work properly it needs credentials with the following permissions:
791
+
792
+ * `s3:ListBucket`
793
+ * `s3:PutObject`
794
+ * `s3:GetObject`
795
+ * `s3:DeleteObject`
796
+ * `s3:PutObjectAcl`
797
+
604
798
  ## Using Rackspace Cloud Files
605
799
 
606
800
  [Fog](http://github.com/fog/fog) is used to support Rackspace Cloud Files. Ensure you have it in your Gemfile:
@@ -610,17 +804,17 @@ gem "fog"
610
804
  ```
611
805
 
612
806
  You'll need to configure a directory (also known as a container), username and API key in the initializer.
613
- For the sake of performance it is assumed that the directory already exists, so please create it if need be.
807
+ For the sake of performance it is assumed that the directory already exists, so please create it if needs to be.
614
808
 
615
809
  Using a US-based account:
616
810
 
617
811
  ```ruby
618
812
  CarrierWave.configure do |config|
619
813
  config.fog_credentials = {
620
- :provider => 'Rackspace',
621
- :rackspace_username => 'xxxxxx',
622
- :rackspace_api_key => 'yyyyyy',
623
- :rackspace_region => :ord # optional, defaults to :dfw
814
+ provider: 'Rackspace',
815
+ rackspace_username: 'xxxxxx',
816
+ rackspace_api_key: 'yyyyyy',
817
+ rackspace_region: :ord # optional, defaults to :dfw
624
818
  }
625
819
  config.fog_directory = 'name_of_directory'
626
820
  end
@@ -631,11 +825,11 @@ Using a UK-based account:
631
825
  ```ruby
632
826
  CarrierWave.configure do |config|
633
827
  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
828
+ provider: 'Rackspace',
829
+ rackspace_username: 'xxxxxx',
830
+ rackspace_api_key: 'yyyyyy',
831
+ rackspace_auth_url: Fog::Rackspace::UK_AUTH_ENDPOINT,
832
+ rackspace_region: :lon
639
833
  }
640
834
  config.fog_directory = 'name_of_directory'
641
835
  end
@@ -660,29 +854,41 @@ end
660
854
  That's it! You can still use the `CarrierWave::Uploader#url` method to return
661
855
  the url to the file on Rackspace Cloud Files.
662
856
 
663
- ## Using Google Storage for Developers
857
+ ## Using Google Cloud Storage
664
858
 
665
- [Fog](http://github.com/fog/fog) is used to support Google Storage for Developers. Ensure you have it in your Gemfile:
859
+ [Fog](http://github.com/fog/fog-google) is used to support Google Cloud Storage. Ensure you have it in your Gemfile:
666
860
 
667
861
  ```ruby
668
- gem "fog"
862
+ gem "fog-google"
669
863
  ```
670
864
 
671
- You'll need to configure a directory (also known as a bucket), access key id and secret access key in the initializer.
672
- For the sake of performance it is assumed that the directory already exists, so please create it if need be.
865
+ You'll need to configure a directory (also known as a bucket) and the credentials in the initializer.
866
+ For the sake of performance it is assumed that the directory already exists, so please create it if needs to be.
673
867
 
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”.
868
+ Please read the [fog-google README](https://github.com/fog/fog-google/blob/master/README.md) on how to get credentials.
676
869
 
870
+ For Google Storage JSON API (recommended):
871
+ ```ruby
872
+ CarrierWave.configure do |config|
873
+ config.fog_credentials = {
874
+ provider: 'Google',
875
+ google_project: 'my-project',
876
+ google_json_key_string: 'xxxxxx'
877
+ # or use google_json_key_location if using an actual file
878
+ }
879
+ config.fog_directory = 'google_cloud_storage_bucket_name'
880
+ end
881
+ ```
677
882
 
883
+ For Google Storage XML API:
678
884
  ```ruby
679
885
  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'
886
+ config.fog_credentials = {
887
+ provider: 'Google',
888
+ google_storage_access_key_id: 'xxxxxx',
889
+ google_storage_secret_access_key: 'yyyyyy'
890
+ }
891
+ config.fog_directory = 'google_cloud_storage_bucket_name'
686
892
  end
687
893
  ```
688
894
 
@@ -697,6 +903,31 @@ end
697
903
  That's it! You can still use the `CarrierWave::Uploader#url` method to return
698
904
  the url to the file on Google.
699
905
 
906
+ ## Optimized Loading of Fog
907
+
908
+ 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:
909
+
910
+ ```ruby
911
+ gem "fog", "~> 1.27", require: "fog/rackspace/storage"
912
+ gem "carrierwave"
913
+ ```
914
+
915
+ A couple of notes about versions:
916
+ * This functionality was introduced in Fog v1.20.
917
+ * This functionality is slated for CarrierWave v1.0.0.
918
+
919
+ If you're not relying on Gemfile entries alone and are requiring "carrierwave" anywhere, ensure you require "fog/rackspace/storage" before it. Ex:
920
+
921
+ ```ruby
922
+ require "fog/rackspace/storage"
923
+ require "carrierwave"
924
+ ```
925
+
926
+ Beware that this specific require is only needed when working with a fog provider that was not extracted to its own gem yet.
927
+ A list of the extracted providers can be found in the page of the `fog` organizations [here](https://github.com/fog).
928
+
929
+ When in doubt, inspect `Fog.constants` to see what has been loaded.
930
+
700
931
  ## Dynamic Asset Host
701
932
 
702
933
  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,12 +941,48 @@ CarrierWave.configure do |config|
710
941
  end
711
942
  ```
712
943
 
713
- ## Using RMagick
944
+ ## Manipulating images
714
945
 
715
946
  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:
947
+ you might want to create thumbnail images for example.
948
+
949
+ ### Using MiniMagick
950
+
951
+ MiniMagick performs all the operations using the 'convert' CLI which is part of the standard ImageMagick kit.
952
+ This allows you to have the power of ImageMagick without having to worry about installing
953
+ all the RMagick libraries, it often results in higher memory footprint.
954
+
955
+ See the MiniMagick site for more details:
956
+
957
+ https://github.com/minimagick/minimagick
958
+
959
+ To install Imagemagick on OSX with homebrew type the following:
960
+
961
+ ```
962
+ $ brew install imagemagick
963
+ ```
964
+
965
+ And the ImageMagick command line options for more for what's on offer:
966
+
967
+ http://www.imagemagick.org/script/command-line-options.php
968
+
969
+ Currently, the MiniMagick carrierwave processor provides exactly the same methods as
970
+ for the RMagick processor.
971
+
972
+ ```ruby
973
+ class AvatarUploader < CarrierWave::Uploader::Base
974
+ include CarrierWave::MiniMagick
975
+
976
+ process resize_to_fill: [200, 200]
977
+ end
978
+ ```
979
+
980
+ See `carrierwave/processing/mini_magick.rb` for details.
981
+
982
+ ### Using RMagick
983
+
984
+ CarrierWave also comes with support for RMagick, a well-known image processing library.
985
+ To use it, you'll need to include this in your Uploader:
719
986
 
720
987
  ```ruby
721
988
  class AvatarUploader < CarrierWave::Uploader::Base
@@ -728,48 +995,66 @@ The RMagick module gives you a few methods, like
728
995
  way. You can set a `process` callback, which will call that method any time a
729
996
  file is uploaded.
730
997
  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.
732
998
 
733
999
  ```ruby
734
1000
  class AvatarUploader < CarrierWave::Uploader::Base
735
1001
  include CarrierWave::RMagick
736
1002
 
737
- process :resize_to_fill => [200, 200]
738
- process :convert => 'png'
739
-
740
- def filename
741
- super.chomp(File.extname(super)) + '.png' if original_filename.present?
742
- end
1003
+ process resize_to_fill: [200, 200]
1004
+ process convert: 'png'
743
1005
  end
744
1006
  ```
745
1007
 
746
1008
  Check out the manipulate! method, which makes it easy for you to write your own
747
1009
  manipulation methods.
748
1010
 
749
- ## Using MiniMagick
1011
+ ### Using Vips
750
1012
 
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.
1013
+ CarrierWave version 2.2.0 added support for the `libvips` image processing library, through [ImageProcessing::Vips](https://github.com/janko/image_processing/blob/master/doc/vips.md). Its functionality matches that of the RMagick and MiniMagick processors, but it uses less memory and offers [faster processing](https://github.com/libvips/libvips/wiki/Speed-and-memory-use). To use the Vips processing module you must first install `libvips`, for example:
754
1014
 
755
- See the MiniMagick site for more details:
1015
+ ````bash
1016
+ $ sudo apt install libvips
1017
+ ````
756
1018
 
757
- https://github.com/minimagick/minimagick
1019
+ You also need to tell your uploader to use Vips:
1020
+
1021
+ ````ruby
1022
+ class ImageFileUploader < CarrierWave::Uploader::Base
1023
+ include CarrierWave::Vips
1024
+ end
1025
+ ````
758
1026
 
759
- And the ImageMagick command line options for more for whats on offer:
1027
+ ### List of available processing methods:
760
1028
 
761
- http://www.imagemagick.org/script/command-line-options.php
1029
+ > [!NOTE]
1030
+ > While the intention is to provide uniform interfaces to all three processing libraries the availability and implementation of processing methods can <a href="supported-processing-methods">vary slightly between them</a>.
762
1031
 
763
- Currently, the MiniMagick carrierwave processor provides exactly the same methods as
764
- for the RMagick processor.
1032
+ - `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.
1033
+ - `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.
1034
+ - `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.
1035
+ - `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".
1036
+ - `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.
1037
+ - `crop` - Crop the image to the contents of a box with the specified height and width, positioned a given number of pixels from the top and left. The original image edge will be retained should the bottom and/or right edge of the box fall outside the image bounds.
765
1038
 
766
- ```ruby
767
- class AvatarUploader < CarrierWave::Uploader::Base
768
- include CarrierWave::MiniMagick
1039
+ #### Supported processing methods
769
1040
 
770
- process :resize_to_fill => [200, 200]
771
- end
772
- ```
1041
+ The following table shows which processing methods are supported by each processing library, and which parameters they accept:
1042
+
1043
+ Method|RMagick|MiniMagick|Vips
1044
+ ------|-----------------|-----------------|-----------------|
1045
+ `convert`|`format`|`format`, `page`<sup>1</sup>|`format`, `page`<sup>1</sup>
1046
+ `resize_to_limit`|`width`, `height`|`width`, `height`|`width`, `height`
1047
+ `resize_to_fit`|`width`, `height`|`width`, `height`|`width`, `height`
1048
+ `resize_to_fill`|`width`, `height`, `gravity`<sup>2</sup>|`width`, `height`, `gravity`<sup>2</sup>|`width`, `height`
1049
+ `resize_and_pad`|`width`, `height`, `background`, `gravity`<sup>2</sup>|`width`, `height`, `background`, `gravity`<sup>2</sup>|`width`, `height`, `background`, `gravity`<sup>2</sup>
1050
+ `resize_to_geometry_string`|`geometry_string`<sup>3</sup>|*not implemented*|*not implemented*
1051
+ `crop`|`left`, `top`, `width`, `height`|`left`, `top`, `width`, `height`|`left`, `top`, `width`, `height`
1052
+
1053
+ <sup>1</sup>`page` refers to the page number when converting from PDF, frame number when converting from GIF, and layer number when converting from PSD.
1054
+
1055
+ <sup>2</sup>`gravity` refers to an image position given as one of `Center`, `North`, `NorthWest`, `West`, `SouthWest`, `South`, `SouthEast`, `East`, or `NorthEast`.
1056
+
1057
+ <sup>3</sup>`geometry_string` is an [ImageMagick geometry string](https://rmagick.github.io/imusage.html#geometry).
773
1058
 
774
1059
  ## Migrating from Paperclip
775
1060
 
@@ -787,28 +1072,36 @@ details.
787
1072
  Be sure to use mount_on to specify the correct column:
788
1073
 
789
1074
  ```ruby
790
- mount_uploader :avatar, AvatarUploader, :mount_on => :avatar_file_name
1075
+ mount_uploader :avatar, AvatarUploader, mount_on: :avatar_file_name
791
1076
  ```
792
1077
 
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
1078
+ ## I18n
798
1079
 
799
- The Active Record validations use the Rails i18n framework. Add these keys to
1080
+ The Active Record validations use the Rails `i18n` framework. Add these keys to
800
1081
  your translations file:
801
1082
 
802
1083
  ```yaml
803
1084
  errors:
804
1085
  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}"
1086
+ carrierwave_processing_error: failed to be processed
1087
+ carrierwave_integrity_error: is not of an allowed file type
1088
+ carrierwave_download_error: could not be downloaded
1089
+ extension_allowlist_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}"
1090
+ extension_denylist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
1091
+ content_type_allowlist_error: "You are not allowed to upload %{content_type} files, allowed types: %{allowed_types}"
1092
+ content_type_denylist_error: "You are not allowed to upload %{content_type} files"
1093
+ processing_error: "Failed to manipulate, maybe it is not an image?"
1094
+ min_size_error: "File size should be greater than %{min_size}"
1095
+ max_size_error: "File size should be less than %{max_size}"
1096
+ min_width_error: "Image width should be greater than %{min_width}px"
1097
+ max_width_error: "Image width should be less than %{max_width}px"
1098
+ min_height_error: "Image height should be greater than %{min_height}px"
1099
+ max_height_error: "Image height should be less than %{max_height}px"
810
1100
  ```
811
1101
 
1102
+ The [`carrierwave-i18n`](https://github.com/carrierwaveuploader/carrierwave-i18n)
1103
+ library adds support for additional locales.
1104
+
812
1105
  ## Large files
813
1106
 
814
1107
  By default, CarrierWave copies an uploaded file twice, first copying the file into the cache, then
@@ -822,6 +1115,7 @@ class MyUploader < CarrierWave::Uploader::Base
822
1115
  def move_to_cache
823
1116
  true
824
1117
  end
1118
+
825
1119
  def move_to_store
826
1120
  true
827
1121
  end
@@ -846,11 +1140,12 @@ end
846
1140
  Will add these callbacks:
847
1141
 
848
1142
  ```ruby
849
- after_save :store_avatar!
850
1143
  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
1144
+ after_save :store_previous_changes_for_avatar
1145
+ after_commit :remove_avatar!, on: :destroy
1146
+ after_commit :mark_remove_avatar_false, on: :update
1147
+ after_commit :remove_previously_stored_avatar, on: :update
1148
+ after_commit :store_avatar!, on: [:create, :update]
854
1149
  ```
855
1150
 
856
1151
  If you want to skip any of these callbacks (eg. you want to keep the existing
@@ -860,17 +1155,44 @@ avatar, even after uploading a new one), you can use ActiveRecord’s
860
1155
  ```ruby
861
1156
  class User
862
1157
  mount_uploader :avatar, AvatarUploader
863
- skip_callback :save, :after, :remove_previously_stored_avatar
1158
+ skip_callback :commit, :after, :remove_previously_stored_avatar
1159
+ end
1160
+ ```
1161
+
1162
+ ## Uploader Callbacks
1163
+
1164
+ In addition to the ActiveRecord callbacks described above, uploaders also have callbacks.
1165
+
1166
+ ```ruby
1167
+ class MyUploader < ::CarrierWave::Uploader::Base
1168
+ before :remove, :log_removal
1169
+ private
1170
+ def log_removal
1171
+ ::Rails.logger.info(format('Deleting file on S3: %s', @file))
1172
+ end
864
1173
  end
865
1174
  ```
866
1175
 
1176
+ Uploader callbacks can be `before` or `after` the following events:
1177
+
1178
+ ```
1179
+ cache
1180
+ process
1181
+ remove
1182
+ retrieve_from_cache
1183
+ retrieve_from_store
1184
+ store
1185
+ ```
1186
+
867
1187
  ## Contributing to CarrierWave
868
1188
 
869
1189
  See [CONTRIBUTING.md](https://github.com/carrierwaveuploader/carrierwave/blob/master/CONTRIBUTING.md)
870
1190
 
871
1191
  ## License
872
1192
 
873
- Copyright (c) 2008-2013 Jonas Nicklas
1193
+ The MIT License (MIT)
1194
+
1195
+ Copyright (c) 2008 Jonas Nicklas
874
1196
 
875
1197
  Permission is hereby granted, free of charge, to any person obtaining
876
1198
  a copy of this software and associated documentation files (the