carrierwave 0.9.0 → 2.1.1
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.
- checksums.yaml +7 -0
- data/README.md +362 -116
- data/lib/carrierwave/compatibility/paperclip.rb +29 -21
- data/lib/carrierwave/downloader/base.rb +83 -0
- data/lib/carrierwave/downloader/remote_file.rb +65 -0
- data/lib/carrierwave/error.rb +1 -0
- data/lib/carrierwave/locale/en.yml +7 -4
- data/lib/carrierwave/mount.rb +238 -186
- data/lib/carrierwave/mounter.rb +188 -0
- data/lib/carrierwave/orm/activerecord.rb +60 -24
- data/lib/carrierwave/processing/mini_magick.rb +139 -78
- data/lib/carrierwave/processing/rmagick.rb +68 -23
- data/lib/carrierwave/processing.rb +0 -1
- data/lib/carrierwave/sanitized_file.rb +67 -27
- data/lib/carrierwave/storage/abstract.rb +15 -2
- data/lib/carrierwave/storage/file.rb +69 -2
- data/lib/carrierwave/storage/fog.rb +180 -41
- data/lib/carrierwave/storage.rb +1 -7
- data/lib/carrierwave/test/matchers.rb +77 -12
- data/lib/carrierwave/uploader/cache.rb +74 -38
- data/lib/carrierwave/uploader/callbacks.rb +0 -2
- data/lib/carrierwave/uploader/configuration.rb +72 -6
- data/lib/carrierwave/uploader/content_type_blacklist.rb +48 -0
- data/lib/carrierwave/uploader/content_type_whitelist.rb +48 -0
- data/lib/carrierwave/uploader/default_url.rb +3 -5
- data/lib/carrierwave/uploader/download.rb +5 -69
- data/lib/carrierwave/uploader/extension_blacklist.rb +14 -10
- data/lib/carrierwave/uploader/extension_whitelist.rb +13 -10
- data/lib/carrierwave/uploader/file_size.rb +43 -0
- data/lib/carrierwave/uploader/mountable.rb +13 -8
- data/lib/carrierwave/uploader/processing.rb +15 -17
- data/lib/carrierwave/uploader/proxy.rb +16 -7
- data/lib/carrierwave/uploader/remove.rb +0 -2
- data/lib/carrierwave/uploader/serialization.rb +3 -5
- data/lib/carrierwave/uploader/store.rb +17 -24
- data/lib/carrierwave/uploader/url.rb +3 -5
- data/lib/carrierwave/uploader/versions.rb +117 -86
- data/lib/carrierwave/uploader.rb +6 -2
- data/lib/carrierwave/utilities/uri.rb +5 -6
- data/lib/carrierwave/utilities.rb +1 -3
- data/lib/carrierwave/validations/active_model.rb +3 -7
- data/lib/carrierwave/version.rb +1 -1
- data/lib/carrierwave.rb +36 -3
- data/lib/generators/templates/uploader.rb +4 -8
- data/lib/generators/uploader_generator.rb +1 -1
- metadata +195 -94
- data/lib/carrierwave/locale/cs.yml +0 -11
- data/lib/carrierwave/locale/de.yml +0 -11
- data/lib/carrierwave/locale/nl.yml +0 -11
- data/lib/carrierwave/locale/sk.yml +0 -11
- data/lib/carrierwave/processing/mime_types.rb +0 -73
data/README.md
CHANGED
|
@@ -3,8 +3,10 @@
|
|
|
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
|
-
[](http://travis-ci.org/carrierwaveuploader/carrierwave)
|
|
7
|
+
[](https://codeclimate.com/github/carrierwaveuploader/carrierwave)
|
|
8
|
+
[](https://dependabot.com/compatibility-score.html?dependency-name=carrierwave&package-manager=bundler&version-scheme=semver)
|
|
9
|
+
|
|
8
10
|
|
|
9
11
|
## Information
|
|
10
12
|
|
|
@@ -14,25 +16,27 @@ It works well with Rack based web applications, such as Ruby on Rails.
|
|
|
14
16
|
|
|
15
17
|
## Getting Help
|
|
16
18
|
|
|
17
|
-
* Please ask the [
|
|
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
|
|
24
|
+
Install the latest release:
|
|
23
25
|
|
|
24
|
-
|
|
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', '~> 2.0'
|
|
30
34
|
```
|
|
31
35
|
|
|
32
36
|
Finally, restart the server to apply the changes.
|
|
33
37
|
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
As of version 2.0, CarrierWave requires Rails 5.0 or higher and Ruby 2.2
|
|
39
|
+
or higher. If you're on Rails 4, you should use 1.x.
|
|
36
40
|
|
|
37
41
|
## Getting Started
|
|
38
42
|
|
|
@@ -85,7 +89,7 @@ a migration:
|
|
|
85
89
|
|
|
86
90
|
|
|
87
91
|
rails g migration add_avatar_to_users avatar:string
|
|
88
|
-
|
|
92
|
+
rails db:migrate
|
|
89
93
|
|
|
90
94
|
Open your model file and mount the uploader:
|
|
91
95
|
|
|
@@ -100,14 +104,22 @@ automatically be stored when the record is saved.
|
|
|
100
104
|
|
|
101
105
|
```ruby
|
|
102
106
|
u = User.new
|
|
103
|
-
u.avatar = params[:file]
|
|
104
|
-
|
|
107
|
+
u.avatar = params[:file] # Assign a file like this, or
|
|
108
|
+
|
|
109
|
+
# like this
|
|
110
|
+
File.open('somewhere') do |f|
|
|
111
|
+
u.avatar = f
|
|
112
|
+
end
|
|
113
|
+
|
|
105
114
|
u.save!
|
|
106
115
|
u.avatar.url # => '/url/to/file.png'
|
|
107
116
|
u.avatar.current_path # => 'path/to/file.png'
|
|
108
|
-
u.
|
|
117
|
+
u.avatar_identifier # => 'file.png'
|
|
109
118
|
```
|
|
110
119
|
|
|
120
|
+
**Note**: `u.avatar` will never return nil, even if there is no photo associated to it.
|
|
121
|
+
To check if a photo was saved to the model, use `u.avatar.file.nil?` instead.
|
|
122
|
+
|
|
111
123
|
### DataMapper, Mongoid, Sequel
|
|
112
124
|
|
|
113
125
|
Other ORM support has been extracted into separate gems:
|
|
@@ -118,6 +130,77 @@ Other ORM support has been extracted into separate gems:
|
|
|
118
130
|
|
|
119
131
|
There are more extensions listed in [the wiki](https://github.com/carrierwaveuploader/carrierwave/wiki)
|
|
120
132
|
|
|
133
|
+
## Multiple file uploads
|
|
134
|
+
|
|
135
|
+
CarrierWave also has convenient support for multiple file upload fields.
|
|
136
|
+
|
|
137
|
+
### ActiveRecord
|
|
138
|
+
|
|
139
|
+
Add a column which can store an array. This could be an array column or a JSON
|
|
140
|
+
column for example. Your choice depends on what your database supports. For
|
|
141
|
+
example, create a migration like this:
|
|
142
|
+
|
|
143
|
+
|
|
144
|
+
#### For databases with ActiveRecord json data type support (e.g. PostgreSQL, MySQL)
|
|
145
|
+
|
|
146
|
+
rails g migration add_avatars_to_users avatars:json
|
|
147
|
+
rails db:migrate
|
|
148
|
+
|
|
149
|
+
#### For database without ActiveRecord json data type support (e.g. SQLite)
|
|
150
|
+
|
|
151
|
+
rails g migration add_avatars_to_users avatars:string
|
|
152
|
+
rails db:migrate
|
|
153
|
+
|
|
154
|
+
__Note__: JSON datatype doesn't exists in SQLite adapter, that's why you can use a string datatype which will be serialized in model.
|
|
155
|
+
|
|
156
|
+
Open your model file and mount the uploader:
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
```ruby
|
|
160
|
+
class User < ActiveRecord::Base
|
|
161
|
+
mount_uploaders :avatars, AvatarUploader
|
|
162
|
+
serialize :avatars, JSON # If you use SQLite, add this line.
|
|
163
|
+
end
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Make sure that you mount the uploader with write (mount_uploaders) with `s` not (mount_uploader)
|
|
167
|
+
in order to avoid errors when uploading multiple files
|
|
168
|
+
|
|
169
|
+
Make sure your file input fields are set up as multiple file fields. For
|
|
170
|
+
example in Rails you'll want to do something like this:
|
|
171
|
+
|
|
172
|
+
```erb
|
|
173
|
+
<%= form.file_field :avatars, multiple: true %>
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
Also, make sure your upload controller permits the multiple file upload attribute, *pointing to an empty array in a hash*. For example:
|
|
177
|
+
|
|
178
|
+
```ruby
|
|
179
|
+
params.require(:user).permit(:email, :first_name, :last_name, {avatars: []})
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Now you can select multiple files in the upload dialog (e.g. SHIFT+SELECT), and they will
|
|
183
|
+
automatically be stored when the record is saved.
|
|
184
|
+
|
|
185
|
+
```ruby
|
|
186
|
+
u = User.new(params[:user])
|
|
187
|
+
u.save!
|
|
188
|
+
u.avatars[0].url # => '/url/to/file.png'
|
|
189
|
+
u.avatars[0].current_path # => 'path/to/file.png'
|
|
190
|
+
u.avatars[0].identifier # => 'file.png'
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
If you want to preserve existing files on uploading new one, you can go like:
|
|
194
|
+
|
|
195
|
+
```erb
|
|
196
|
+
<% user.avatars.each do |avatar| %>
|
|
197
|
+
<%= hidden_field :user, :avatars, multiple: true, value: avatar.identifier %>
|
|
198
|
+
<% end %>
|
|
199
|
+
<%= form.file_field :avatars, multiple: true %>
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
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).
|
|
203
|
+
|
|
121
204
|
## Changing the storage directory
|
|
122
205
|
|
|
123
206
|
In order to change where uploaded files are put, just override the `store_dir`
|
|
@@ -146,97 +229,140 @@ end
|
|
|
146
229
|
|
|
147
230
|
## Securing uploads
|
|
148
231
|
|
|
149
|
-
Certain
|
|
150
|
-
files or other script files. CarrierWave allows you to specify a
|
|
151
|
-
allowed extensions.
|
|
232
|
+
Certain files might be dangerous if uploaded to the wrong location, such as PHP
|
|
233
|
+
files or other script files. CarrierWave allows you to specify a whitelist of
|
|
234
|
+
allowed extensions or content types.
|
|
152
235
|
|
|
153
236
|
If you're mounting the uploader, uploading a file with the wrong extension will
|
|
154
237
|
make the record invalid instead. Otherwise, an error is raised.
|
|
155
238
|
|
|
156
239
|
```ruby
|
|
157
240
|
class MyUploader < CarrierWave::Uploader::Base
|
|
158
|
-
def
|
|
241
|
+
def extension_whitelist
|
|
159
242
|
%w(jpg jpeg gif png)
|
|
160
243
|
end
|
|
161
244
|
end
|
|
162
245
|
```
|
|
163
246
|
|
|
247
|
+
The same thing could be done using content types.
|
|
248
|
+
Let's say we need an uploader that accepts only images. This can be done like this
|
|
249
|
+
|
|
250
|
+
```ruby
|
|
251
|
+
class MyUploader < CarrierWave::Uploader::Base
|
|
252
|
+
def content_type_whitelist
|
|
253
|
+
/image\//
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
You can use a blacklist to reject content types.
|
|
259
|
+
Let's say we need an uploader that reject JSON files. This can be done like this
|
|
260
|
+
|
|
261
|
+
```ruby
|
|
262
|
+
class NoJsonUploader < CarrierWave::Uploader::Base
|
|
263
|
+
def content_type_blacklist
|
|
264
|
+
['application/text', 'application/json']
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
### CVE-2016-3714 (ImageTragick)
|
|
270
|
+
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.
|
|
271
|
+
|
|
272
|
+
|
|
273
|
+
A valid whitelist that will restrict your uploader to images only, and mitigate the CVE is:
|
|
274
|
+
|
|
275
|
+
```ruby
|
|
276
|
+
class MyUploader < CarrierWave::Uploader::Base
|
|
277
|
+
def content_type_whitelist
|
|
278
|
+
[/image\//]
|
|
279
|
+
end
|
|
280
|
+
end
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
**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_whitelist` will not inspect the file headers, and thus still leaves your application open to the vulnerability.
|
|
284
|
+
|
|
164
285
|
### Filenames and unicode chars
|
|
165
286
|
|
|
166
287
|
Another security issue you should care for is the file names (see
|
|
167
288
|
[Ruby On Rails Security Guide](http://guides.rubyonrails.org/security.html#file-uploads)).
|
|
168
|
-
By default, CarrierWave provides only English letters, arabic numerals and
|
|
289
|
+
By default, CarrierWave provides only English letters, arabic numerals and some symbols as
|
|
169
290
|
white-listed characters in the file name. If you want to support local scripts (Cyrillic letters, letters with diacritics and so on), you
|
|
170
291
|
have to override `sanitize_regexp` method. It should return regular expression which would match
|
|
171
292
|
all *non*-allowed symbols.
|
|
172
293
|
|
|
173
|
-
With Ruby 1.9 and higher you can simply write (as it has [Oniguruma](http://oniguruma.rubyforge.org/oniguruma/)
|
|
174
|
-
built-in):
|
|
175
|
-
|
|
176
294
|
```ruby
|
|
177
295
|
CarrierWave::SanitizedFile.sanitize_regexp = /[^[:word:]\.\-\+]/
|
|
178
296
|
```
|
|
179
297
|
|
|
180
|
-
With Ruby 1.8 you have to manually specify all character ranges. For example, for files which may
|
|
181
|
-
contain Russian letters:
|
|
182
|
-
|
|
183
|
-
```ruby
|
|
184
|
-
CarrierWave::SanitizedFile.sanitize_regexp = /[^a-zA-Zа-яА-ЯёЁ0-9\.\-\+_]/u
|
|
185
|
-
```
|
|
186
|
-
|
|
187
298
|
Also make sure that allowing non-latin characters won't cause a compatibility issue with a third-party
|
|
188
299
|
plugins or client-side software.
|
|
189
300
|
|
|
190
301
|
## Setting the content type
|
|
191
302
|
|
|
192
|
-
|
|
193
|
-
|
|
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.
|
|
303
|
+
As of v0.11.0, the `mime-types` gem is a runtime dependency and the content type is set automatically.
|
|
304
|
+
You no longer need to do this manually.
|
|
196
305
|
|
|
197
|
-
|
|
198
|
-
require 'carrierwave/processing/mime_types'
|
|
306
|
+
## Adding versions
|
|
199
307
|
|
|
200
|
-
|
|
201
|
-
include CarrierWave::MimeTypes
|
|
308
|
+
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*:
|
|
202
309
|
|
|
203
|
-
|
|
204
|
-
end
|
|
205
|
-
```
|
|
310
|
+
*Note:* You must have Imagemagick installed to do image resizing.
|
|
206
311
|
|
|
207
|
-
|
|
312
|
+
Some documentation refers to RMagick instead of MiniMagick but MiniMagick is recommended.
|
|
208
313
|
|
|
209
|
-
|
|
210
|
-
|
|
314
|
+
To install Imagemagick on OSX with homebrew type the following:
|
|
315
|
+
|
|
316
|
+
```
|
|
317
|
+
$ brew install imagemagick
|
|
318
|
+
```
|
|
211
319
|
|
|
212
320
|
```ruby
|
|
213
321
|
class MyUploader < CarrierWave::Uploader::Base
|
|
214
|
-
include CarrierWave::
|
|
322
|
+
include CarrierWave::MiniMagick
|
|
215
323
|
|
|
216
|
-
process :
|
|
324
|
+
process resize_to_fit: [800, 800]
|
|
217
325
|
|
|
218
326
|
version :thumb do
|
|
219
|
-
process :
|
|
327
|
+
process resize_to_fill: [200,200]
|
|
220
328
|
end
|
|
221
329
|
|
|
222
330
|
end
|
|
223
331
|
```
|
|
224
332
|
|
|
225
333
|
When this uploader is used, an uploaded image would be scaled to be no larger
|
|
226
|
-
than 800 by 800 pixels.
|
|
227
|
-
|
|
334
|
+
than 800 by 800 pixels. The original aspect ratio will be kept.
|
|
335
|
+
|
|
336
|
+
A version called `:thumb` is then created, which is scaled
|
|
337
|
+
to exactly 200 by 200 pixels. The thumbnail uses `resize_to_fill` which makes sure
|
|
338
|
+
that the width and height specified are filled, only cropping
|
|
339
|
+
if the aspect ratio requires it.
|
|
340
|
+
|
|
341
|
+
The above uploader could be used like this:
|
|
228
342
|
|
|
229
343
|
```ruby
|
|
230
344
|
uploader = AvatarUploader.new
|
|
231
345
|
uploader.store!(my_file) # size: 1024x768
|
|
232
346
|
|
|
233
|
-
uploader.url # => '/url/to/my_file.png' # size:
|
|
347
|
+
uploader.url # => '/url/to/my_file.png' # size: 800x800
|
|
234
348
|
uploader.thumb.url # => '/url/to/thumb_my_file.png' # size: 200x200
|
|
235
349
|
```
|
|
236
350
|
|
|
237
351
|
One important thing to remember is that process is called *before* versions are
|
|
238
352
|
created. This can cut down on processing cost.
|
|
239
353
|
|
|
354
|
+
### Processing Methods: mini_magick
|
|
355
|
+
|
|
356
|
+
- `convert` - Changes the image encoding format to the given format, eg. jpg
|
|
357
|
+
- `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.
|
|
358
|
+
- `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.
|
|
359
|
+
- `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".
|
|
360
|
+
- `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.
|
|
361
|
+
|
|
362
|
+
See `carrierwave/processing/mini_magick.rb` for details.
|
|
363
|
+
|
|
364
|
+
### Nested versions
|
|
365
|
+
|
|
240
366
|
It is possible to nest versions within versions:
|
|
241
367
|
|
|
242
368
|
```ruby
|
|
@@ -258,11 +384,11 @@ properties within the model or based on the picture itself.
|
|
|
258
384
|
```ruby
|
|
259
385
|
class MyUploader < CarrierWave::Uploader::Base
|
|
260
386
|
|
|
261
|
-
version :human, :
|
|
262
|
-
version :monkey, :
|
|
263
|
-
version :banner, :
|
|
387
|
+
version :human, if: :is_human?
|
|
388
|
+
version :monkey, if: :is_monkey?
|
|
389
|
+
version :banner, if: :is_landscape?
|
|
264
390
|
|
|
265
|
-
|
|
391
|
+
private
|
|
266
392
|
|
|
267
393
|
def is_human? picture
|
|
268
394
|
model.can_program?(:ruby)
|
|
@@ -273,7 +399,7 @@ protected
|
|
|
273
399
|
end
|
|
274
400
|
|
|
275
401
|
def is_landscape? picture
|
|
276
|
-
image = MiniMagick::Image.
|
|
402
|
+
image = MiniMagick::Image.new(picture.path)
|
|
277
403
|
image[:width] > image[:height]
|
|
278
404
|
end
|
|
279
405
|
|
|
@@ -296,7 +422,7 @@ class MyUploader < CarrierWave::Uploader::Base
|
|
|
296
422
|
process resize_to_fill: [280, 280]
|
|
297
423
|
end
|
|
298
424
|
|
|
299
|
-
version :small_thumb, :
|
|
425
|
+
version :small_thumb, from_version: :thumb do
|
|
300
426
|
process resize_to_fill: [20, 20]
|
|
301
427
|
end
|
|
302
428
|
|
|
@@ -315,7 +441,7 @@ file, just add a hidden field called `avatar_cache` (don't forget to add it to
|
|
|
315
441
|
the attr_accessible list as necessary). In Rails, this would look like this:
|
|
316
442
|
|
|
317
443
|
```erb
|
|
318
|
-
<%= form_for @user, :
|
|
444
|
+
<%= form_for @user, html: { multipart: true } do |f| %>
|
|
319
445
|
<p>
|
|
320
446
|
<label>My Avatar</label>
|
|
321
447
|
<%= f.file_field :avatar %>
|
|
@@ -328,7 +454,7 @@ It might be a good idea to show the user that a file has been uploaded, in the
|
|
|
328
454
|
case of images, a small thumbnail would be a good indicator:
|
|
329
455
|
|
|
330
456
|
```erb
|
|
331
|
-
<%= form_for @user, :
|
|
457
|
+
<%= form_for @user, html: { multipart: true } do |f| %>
|
|
332
458
|
<p>
|
|
333
459
|
<label>My Avatar</label>
|
|
334
460
|
<%= image_tag(@user.avatar_url) if @user.avatar? %>
|
|
@@ -344,7 +470,7 @@ If you want to remove a previously uploaded file on a mounted uploader, you can
|
|
|
344
470
|
easily add a checkbox to the form which will remove the file when checked.
|
|
345
471
|
|
|
346
472
|
```erb
|
|
347
|
-
<%= form_for @user, :
|
|
473
|
+
<%= form_for @user, html: { multipart: true } do |f| %>
|
|
348
474
|
<p>
|
|
349
475
|
<label>My Avatar</label>
|
|
350
476
|
<%= image_tag(@user.avatar_url) if @user.avatar? %>
|
|
@@ -360,7 +486,13 @@ easily add a checkbox to the form which will remove the file when checked.
|
|
|
360
486
|
<% end %>
|
|
361
487
|
```
|
|
362
488
|
|
|
363
|
-
If you want to remove the file manually, you can call <code>remove_avatar!</code
|
|
489
|
+
If you want to remove the file manually, you can call <code>remove_avatar!</code>, then save the object.
|
|
490
|
+
|
|
491
|
+
```erb
|
|
492
|
+
@user.remove_avatar!
|
|
493
|
+
@user.save
|
|
494
|
+
#=> true
|
|
495
|
+
```
|
|
364
496
|
|
|
365
497
|
## Uploading files from a remote location
|
|
366
498
|
|
|
@@ -369,7 +501,7 @@ via a URL. CarrierWave makes this simple, just add the appropriate attribute to
|
|
|
369
501
|
form and you're good to go:
|
|
370
502
|
|
|
371
503
|
```erb
|
|
372
|
-
<%= form_for @user, :
|
|
504
|
+
<%= form_for @user, html: { multipart: true } do |f| %>
|
|
373
505
|
<p>
|
|
374
506
|
<label>My Avatar URL:</label>
|
|
375
507
|
<%= image_tag(@user.avatar_url) if @user.avatar? %>
|
|
@@ -391,7 +523,7 @@ this easily by overriding the `default_url` method in your uploader:
|
|
|
391
523
|
|
|
392
524
|
```ruby
|
|
393
525
|
class MyUploader < CarrierWave::Uploader::Base
|
|
394
|
-
def default_url
|
|
526
|
+
def default_url(*args)
|
|
395
527
|
"/images/fallback/" + [version_name, "default.png"].compact.join('_')
|
|
396
528
|
end
|
|
397
529
|
end
|
|
@@ -401,7 +533,7 @@ Or if you are using the Rails asset pipeline:
|
|
|
401
533
|
|
|
402
534
|
```ruby
|
|
403
535
|
class MyUploader < CarrierWave::Uploader::Base
|
|
404
|
-
def default_url
|
|
536
|
+
def default_url(*args)
|
|
405
537
|
ActionController::Base.helpers.asset_path("fallback/" + [version_name, "default.png"].compact.join('_'))
|
|
406
538
|
end
|
|
407
539
|
end
|
|
@@ -428,11 +560,19 @@ instance.recreate_versions!(:thumb, :large)
|
|
|
428
560
|
Or on a mounted uploader:
|
|
429
561
|
|
|
430
562
|
```ruby
|
|
431
|
-
User.
|
|
563
|
+
User.find_each do |user|
|
|
432
564
|
user.avatar.recreate_versions!
|
|
433
565
|
end
|
|
434
566
|
```
|
|
435
567
|
|
|
568
|
+
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:
|
|
569
|
+
|
|
570
|
+
```ruby
|
|
571
|
+
User.find_each do |user|
|
|
572
|
+
user.avatar.recreate_versions! if user.avatar?
|
|
573
|
+
end
|
|
574
|
+
```
|
|
575
|
+
|
|
436
576
|
## Configuring CarrierWave
|
|
437
577
|
|
|
438
578
|
CarrierWave has a broad range of configuration options, which you can configure,
|
|
@@ -458,6 +598,16 @@ If you're using Rails, create an initializer for this:
|
|
|
458
598
|
|
|
459
599
|
config/initializers/carrierwave.rb
|
|
460
600
|
|
|
601
|
+
If you want CarrierWave to fail noisily in development, you can change these configs in your environment file:
|
|
602
|
+
|
|
603
|
+
```ruby
|
|
604
|
+
CarrierWave.configure do |config|
|
|
605
|
+
config.ignore_integrity_errors = false
|
|
606
|
+
config.ignore_processing_errors = false
|
|
607
|
+
config.ignore_download_errors = false
|
|
608
|
+
end
|
|
609
|
+
```
|
|
610
|
+
|
|
461
611
|
|
|
462
612
|
## Testing with CarrierWave
|
|
463
613
|
|
|
@@ -474,6 +624,9 @@ if Rails.env.test? or Rails.env.cucumber?
|
|
|
474
624
|
end
|
|
475
625
|
```
|
|
476
626
|
|
|
627
|
+
Remember, if you have already set `storage :something` in your uploader, the `storage`
|
|
628
|
+
setting from this initializer will be ignored.
|
|
629
|
+
|
|
477
630
|
If you need to test your processing, you should test it in isolation, and enable
|
|
478
631
|
processing only for those tests that need it.
|
|
479
632
|
|
|
@@ -485,35 +638,43 @@ require 'carrierwave/test/matchers'
|
|
|
485
638
|
describe MyUploader do
|
|
486
639
|
include CarrierWave::Test::Matchers
|
|
487
640
|
|
|
641
|
+
let(:user) { double('user') }
|
|
642
|
+
let(:uploader) { MyUploader.new(user, :avatar) }
|
|
643
|
+
|
|
488
644
|
before do
|
|
489
645
|
MyUploader.enable_processing = true
|
|
490
|
-
|
|
491
|
-
@uploader.store!(File.open(path_to_file))
|
|
646
|
+
File.open(path_to_file) { |f| uploader.store!(f) }
|
|
492
647
|
end
|
|
493
648
|
|
|
494
649
|
after do
|
|
495
650
|
MyUploader.enable_processing = false
|
|
496
|
-
|
|
651
|
+
uploader.remove!
|
|
497
652
|
end
|
|
498
653
|
|
|
499
654
|
context 'the thumb version' do
|
|
500
|
-
it "
|
|
501
|
-
|
|
655
|
+
it "scales down a landscape image to be exactly 64 by 64 pixels" do
|
|
656
|
+
expect(uploader.thumb).to have_dimensions(64, 64)
|
|
502
657
|
end
|
|
503
658
|
end
|
|
504
659
|
|
|
505
660
|
context 'the small version' do
|
|
506
|
-
it "
|
|
507
|
-
|
|
661
|
+
it "scales down a landscape image to fit within 200 by 200 pixels" do
|
|
662
|
+
expect(uploader.small).to be_no_larger_than(200, 200)
|
|
508
663
|
end
|
|
509
664
|
end
|
|
510
665
|
|
|
511
|
-
it "
|
|
512
|
-
|
|
666
|
+
it "makes the image readable only to the owner and not executable" do
|
|
667
|
+
expect(uploader).to have_permissions(0600)
|
|
668
|
+
end
|
|
669
|
+
|
|
670
|
+
it "has the correct format" do
|
|
671
|
+
expect(uploader).to be_format('png')
|
|
513
672
|
end
|
|
514
673
|
end
|
|
515
674
|
```
|
|
516
675
|
|
|
676
|
+
If you're looking for minitest asserts, checkout [carrierwave_asserts](https://github.com/hcfairbanks/carrierwave_asserts).
|
|
677
|
+
|
|
517
678
|
Setting the enable_processing flag on an uploader will prevent any of the versions from processing as well.
|
|
518
679
|
Processing can be enabled for a single version by setting the processing flag on the version like so:
|
|
519
680
|
|
|
@@ -521,31 +682,41 @@ Processing can be enabled for a single version by setting the processing flag on
|
|
|
521
682
|
@uploader.thumb.enable_processing = true
|
|
522
683
|
```
|
|
523
684
|
|
|
685
|
+
## Fog
|
|
686
|
+
|
|
687
|
+
If you want to use fog you must add in your CarrierWave initializer the
|
|
688
|
+
following lines
|
|
689
|
+
|
|
690
|
+
```ruby
|
|
691
|
+
config.fog_credentials = { ... } # Provider specific credentials
|
|
692
|
+
```
|
|
693
|
+
|
|
524
694
|
## Using Amazon S3
|
|
525
695
|
|
|
526
|
-
[Fog](http://github.com/fog/fog) is used to support Amazon S3. Ensure you have it in your Gemfile:
|
|
696
|
+
[Fog AWS](http://github.com/fog/fog-aws) is used to support Amazon S3. Ensure you have it in your Gemfile:
|
|
527
697
|
|
|
528
698
|
```ruby
|
|
529
|
-
gem "fog"
|
|
699
|
+
gem "fog-aws"
|
|
530
700
|
```
|
|
531
701
|
|
|
532
702
|
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
|
|
703
|
+
For the sake of performance it is assumed that the directory already exists, so please create it if it needs to be.
|
|
534
704
|
You can also pass in additional options, as documented fully in lib/carrierwave/storage/fog.rb. Here's a full example:
|
|
535
705
|
|
|
536
706
|
```ruby
|
|
537
707
|
CarrierWave.configure do |config|
|
|
538
708
|
config.fog_credentials = {
|
|
539
|
-
:
|
|
540
|
-
:
|
|
541
|
-
:
|
|
542
|
-
:
|
|
543
|
-
:
|
|
544
|
-
:
|
|
709
|
+
provider: 'AWS', # required
|
|
710
|
+
aws_access_key_id: 'xxx', # required unless using use_iam_profile
|
|
711
|
+
aws_secret_access_key: 'yyy', # required unless using use_iam_profile
|
|
712
|
+
use_iam_profile: true, # optional, defaults to false
|
|
713
|
+
region: 'eu-west-1', # optional, defaults to 'us-east-1'
|
|
714
|
+
host: 's3.example.com', # optional, defaults to nil
|
|
715
|
+
endpoint: 'https://s3.example.com:8080' # optional, defaults to nil
|
|
545
716
|
}
|
|
546
|
-
config.fog_directory = '
|
|
547
|
-
config.fog_public = false
|
|
548
|
-
config.fog_attributes = {
|
|
717
|
+
config.fog_directory = 'name_of_bucket' # required
|
|
718
|
+
config.fog_public = false # optional, defaults to true
|
|
719
|
+
config.fog_attributes = { cache_control: "public, max-age=#{365.days.to_i}" } # optional, defaults to {}
|
|
549
720
|
end
|
|
550
721
|
```
|
|
551
722
|
|
|
@@ -559,12 +730,20 @@ end
|
|
|
559
730
|
|
|
560
731
|
That's it! You can still use the `CarrierWave::Uploader#url` method to return the url to the file on Amazon S3.
|
|
561
732
|
|
|
733
|
+
**Note**: for Carrierwave to work properly it needs credentials with the following permissions:
|
|
734
|
+
|
|
735
|
+
* `s3:ListBucket`
|
|
736
|
+
* `s3:PutObject`
|
|
737
|
+
* `s3:GetObject`
|
|
738
|
+
* `s3:DeleteObject`
|
|
739
|
+
* `s3:PutObjectAcl`
|
|
740
|
+
|
|
562
741
|
## Using Rackspace Cloud Files
|
|
563
742
|
|
|
564
743
|
[Fog](http://github.com/fog/fog) is used to support Rackspace Cloud Files. Ensure you have it in your Gemfile:
|
|
565
744
|
|
|
566
745
|
```ruby
|
|
567
|
-
gem "fog"
|
|
746
|
+
gem "fog"
|
|
568
747
|
```
|
|
569
748
|
|
|
570
749
|
You'll need to configure a directory (also known as a container), username and API key in the initializer.
|
|
@@ -575,10 +754,10 @@ Using a US-based account:
|
|
|
575
754
|
```ruby
|
|
576
755
|
CarrierWave.configure do |config|
|
|
577
756
|
config.fog_credentials = {
|
|
578
|
-
:
|
|
579
|
-
:
|
|
580
|
-
:
|
|
581
|
-
:
|
|
757
|
+
provider: 'Rackspace',
|
|
758
|
+
rackspace_username: 'xxxxxx',
|
|
759
|
+
rackspace_api_key: 'yyyyyy',
|
|
760
|
+
rackspace_region: :ord # optional, defaults to :dfw
|
|
582
761
|
}
|
|
583
762
|
config.fog_directory = 'name_of_directory'
|
|
584
763
|
end
|
|
@@ -589,11 +768,11 @@ Using a UK-based account:
|
|
|
589
768
|
```ruby
|
|
590
769
|
CarrierWave.configure do |config|
|
|
591
770
|
config.fog_credentials = {
|
|
592
|
-
:
|
|
593
|
-
:
|
|
594
|
-
:
|
|
595
|
-
:
|
|
596
|
-
:
|
|
771
|
+
provider: 'Rackspace',
|
|
772
|
+
rackspace_username: 'xxxxxx',
|
|
773
|
+
rackspace_api_key: 'yyyyyy',
|
|
774
|
+
rackspace_auth_url: Fog::Rackspace::UK_AUTH_ENDPOINT,
|
|
775
|
+
rackspace_region: :lon
|
|
597
776
|
}
|
|
598
777
|
config.fog_directory = 'name_of_directory'
|
|
599
778
|
end
|
|
@@ -620,25 +799,26 @@ the url to the file on Rackspace Cloud Files.
|
|
|
620
799
|
|
|
621
800
|
## Using Google Storage for Developers
|
|
622
801
|
|
|
623
|
-
[Fog](http://github.com/fog/fog) is used to support Google Storage for Developers. Ensure you have it in your Gemfile:
|
|
802
|
+
[Fog](http://github.com/fog/fog-google) is used to support Google Storage for Developers. Ensure you have it in your Gemfile:
|
|
624
803
|
|
|
625
804
|
```ruby
|
|
626
|
-
gem "fog"
|
|
805
|
+
gem "fog-google"
|
|
806
|
+
gem "google-api-client", "> 0.8.5", "< 0.9"
|
|
807
|
+
gem "mime-types"
|
|
627
808
|
```
|
|
628
809
|
|
|
629
810
|
You'll need to configure a directory (also known as a bucket), access key id and secret access key in the initializer.
|
|
630
811
|
For the sake of performance it is assumed that the directory already exists, so please create it if need be.
|
|
631
812
|
|
|
632
|
-
|
|
633
|
-
under the section “Interoperable Access”.
|
|
813
|
+
Please read the [fog-google README](https://github.com/fog/fog-google/blob/master/README.md) on how to get credentials.
|
|
634
814
|
|
|
635
815
|
|
|
636
816
|
```ruby
|
|
637
817
|
CarrierWave.configure do |config|
|
|
638
818
|
config.fog_credentials = {
|
|
639
|
-
:
|
|
640
|
-
:
|
|
641
|
-
:
|
|
819
|
+
provider: 'Google',
|
|
820
|
+
google_storage_access_key_id: 'xxxxxx',
|
|
821
|
+
google_storage_secret_access_key: 'yyyyyy'
|
|
642
822
|
}
|
|
643
823
|
config.fog_directory = 'name_of_directory'
|
|
644
824
|
end
|
|
@@ -655,6 +835,31 @@ end
|
|
|
655
835
|
That's it! You can still use the `CarrierWave::Uploader#url` method to return
|
|
656
836
|
the url to the file on Google.
|
|
657
837
|
|
|
838
|
+
## Optimized Loading of Fog
|
|
839
|
+
|
|
840
|
+
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:
|
|
841
|
+
|
|
842
|
+
```ruby
|
|
843
|
+
gem "fog", "~> 1.27", require: "fog/rackspace/storage"
|
|
844
|
+
gem "carrierwave"
|
|
845
|
+
```
|
|
846
|
+
|
|
847
|
+
A couple of notes about versions:
|
|
848
|
+
* This functionality was introduced in Fog v1.20.
|
|
849
|
+
* This functionality is slated for CarrierWave v1.0.0.
|
|
850
|
+
|
|
851
|
+
If you're not relying on Gemfile entries alone and are requiring "carrierwave" anywhere, ensure you require "fog/rackspace/storage" before it. Ex:
|
|
852
|
+
|
|
853
|
+
```ruby
|
|
854
|
+
require "fog/rackspace/storage"
|
|
855
|
+
require "carrierwave"
|
|
856
|
+
```
|
|
857
|
+
|
|
858
|
+
Beware that this specific require is only needed when working with a fog provider that was not extracted to its own gem yet.
|
|
859
|
+
A list of the extracted providers can be found in the page of the `fog` organizations [here](https://github.com/fog).
|
|
860
|
+
|
|
861
|
+
When in doubt, inspect `Fog.constants` to see what has been loaded.
|
|
862
|
+
|
|
658
863
|
## Dynamic Asset Host
|
|
659
864
|
|
|
660
865
|
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.
|
|
@@ -692,11 +897,11 @@ Convert will only work if the file has the same file extension, thus the use of
|
|
|
692
897
|
class AvatarUploader < CarrierWave::Uploader::Base
|
|
693
898
|
include CarrierWave::RMagick
|
|
694
899
|
|
|
695
|
-
process :
|
|
696
|
-
process :
|
|
900
|
+
process resize_to_fill: [200, 200]
|
|
901
|
+
process convert: 'png'
|
|
697
902
|
|
|
698
903
|
def filename
|
|
699
|
-
super.chomp(File.extname(super)) + '.png'
|
|
904
|
+
super.chomp(File.extname(super)) + '.png' if original_filename.present?
|
|
700
905
|
end
|
|
701
906
|
end
|
|
702
907
|
```
|
|
@@ -706,8 +911,8 @@ manipulation methods.
|
|
|
706
911
|
|
|
707
912
|
## Using MiniMagick
|
|
708
913
|
|
|
709
|
-
MiniMagick is similar to RMagick but performs all the operations using the '
|
|
710
|
-
|
|
914
|
+
MiniMagick is similar to RMagick but performs all the operations using the 'convert'
|
|
915
|
+
CLI which is part of the standard ImageMagick kit. This allows you to have the power
|
|
711
916
|
of ImageMagick without having to worry about installing all the RMagick libraries.
|
|
712
917
|
|
|
713
918
|
See the MiniMagick site for more details:
|
|
@@ -725,7 +930,7 @@ for the RMagick processor.
|
|
|
725
930
|
class AvatarUploader < CarrierWave::Uploader::Base
|
|
726
931
|
include CarrierWave::MiniMagick
|
|
727
932
|
|
|
728
|
-
process :
|
|
933
|
+
process resize_to_fill: [200, 200]
|
|
729
934
|
end
|
|
730
935
|
```
|
|
731
936
|
|
|
@@ -745,26 +950,33 @@ details.
|
|
|
745
950
|
Be sure to use mount_on to specify the correct column:
|
|
746
951
|
|
|
747
952
|
```ruby
|
|
748
|
-
mount_uploader :avatar, AvatarUploader, :
|
|
953
|
+
mount_uploader :avatar, AvatarUploader, mount_on: :avatar_file_name
|
|
749
954
|
```
|
|
750
955
|
|
|
751
|
-
|
|
752
|
-
sensible compatibility mode. Patches for migrating from other solutions will be
|
|
753
|
-
happily accepted.
|
|
956
|
+
## I18n
|
|
754
957
|
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
The Active Record validations use the Rails i18n framework. Add these keys to
|
|
958
|
+
The Active Record validations use the Rails `i18n` framework. Add these keys to
|
|
758
959
|
your translations file:
|
|
759
960
|
|
|
760
961
|
```yaml
|
|
761
962
|
errors:
|
|
762
963
|
messages:
|
|
763
|
-
carrierwave_processing_error:
|
|
764
|
-
carrierwave_integrity_error:
|
|
765
|
-
carrierwave_download_error:
|
|
964
|
+
carrierwave_processing_error: failed to be processed
|
|
965
|
+
carrierwave_integrity_error: is not of an allowed file type
|
|
966
|
+
carrierwave_download_error: could not be downloaded
|
|
967
|
+
extension_whitelist_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}"
|
|
968
|
+
extension_blacklist_error: "You are not allowed to upload %{extension} files, prohibited types: %{prohibited_types}"
|
|
969
|
+
content_type_whitelist_error: "You are not allowed to upload %{content_type} files, allowed types: %{allowed_types}"
|
|
970
|
+
content_type_blacklist_error: "You are not allowed to upload %{content_type} files"
|
|
971
|
+
rmagick_processing_error: "Failed to manipulate with rmagick, maybe it is not an image?"
|
|
972
|
+
mini_magick_processing_error: "Failed to manipulate with MiniMagick, maybe it is not an image? Original Error: %{e}"
|
|
973
|
+
min_size_error: "File size should be greater than %{min_size}"
|
|
974
|
+
max_size_error: "File size should be less than %{max_size}"
|
|
766
975
|
```
|
|
767
976
|
|
|
977
|
+
The [`carrierwave-i18n`](https://github.com/carrierwaveuploader/carrierwave-i18n)
|
|
978
|
+
library adds support for additional locales.
|
|
979
|
+
|
|
768
980
|
## Large files
|
|
769
981
|
|
|
770
982
|
By default, CarrierWave copies an uploaded file twice, first copying the file into the cache, then
|
|
@@ -778,6 +990,7 @@ class MyUploader < CarrierWave::Uploader::Base
|
|
|
778
990
|
def move_to_cache
|
|
779
991
|
true
|
|
780
992
|
end
|
|
993
|
+
|
|
781
994
|
def move_to_store
|
|
782
995
|
true
|
|
783
996
|
end
|
|
@@ -788,13 +1001,46 @@ When the `move_to_cache` and/or `move_to_store` methods return true, files will
|
|
|
788
1001
|
|
|
789
1002
|
This has only been tested with the local filesystem store.
|
|
790
1003
|
|
|
1004
|
+
## Skipping ActiveRecord callbacks
|
|
1005
|
+
|
|
1006
|
+
By default, mounting an uploader into an ActiveRecord model will add a few
|
|
1007
|
+
callbacks. For example, this code:
|
|
1008
|
+
|
|
1009
|
+
```ruby
|
|
1010
|
+
class User
|
|
1011
|
+
mount_uploader :avatar, AvatarUploader
|
|
1012
|
+
end
|
|
1013
|
+
```
|
|
1014
|
+
|
|
1015
|
+
Will add these callbacks:
|
|
1016
|
+
|
|
1017
|
+
```ruby
|
|
1018
|
+
after_save :store_avatar!
|
|
1019
|
+
before_save :write_avatar_identifier
|
|
1020
|
+
after_commit :remove_avatar!, on: :destroy
|
|
1021
|
+
after_commit :mark_remove_avatar_false, on: :update
|
|
1022
|
+
after_save :store_previous_changes_for_avatar
|
|
1023
|
+
after_commit :remove_previously_stored_avatar, on: :update
|
|
1024
|
+
```
|
|
1025
|
+
|
|
1026
|
+
If you want to skip any of these callbacks (eg. you want to keep the existing
|
|
1027
|
+
avatar, even after uploading a new one), you can use ActiveRecord’s
|
|
1028
|
+
`skip_callback` method.
|
|
1029
|
+
|
|
1030
|
+
```ruby
|
|
1031
|
+
class User
|
|
1032
|
+
mount_uploader :avatar, AvatarUploader
|
|
1033
|
+
skip_callback :commit, :after, :remove_previously_stored_avatar
|
|
1034
|
+
end
|
|
1035
|
+
```
|
|
1036
|
+
|
|
791
1037
|
## Contributing to CarrierWave
|
|
792
1038
|
|
|
793
1039
|
See [CONTRIBUTING.md](https://github.com/carrierwaveuploader/carrierwave/blob/master/CONTRIBUTING.md)
|
|
794
1040
|
|
|
795
1041
|
## License
|
|
796
1042
|
|
|
797
|
-
Copyright (c) 2008-
|
|
1043
|
+
Copyright (c) 2008-2015 Jonas Nicklas
|
|
798
1044
|
|
|
799
1045
|
Permission is hereby granted, free of charge, to any person obtaining
|
|
800
1046
|
a copy of this software and associated documentation files (the
|