paperclip 4.2.2 → 6.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.codeclimate.yml +17 -0
- data/.github/issue_template.md +3 -0
- data/.hound.yml +1055 -0
- data/.rubocop.yml +1 -0
- data/.travis.yml +17 -15
- data/Appraisals +4 -16
- data/CONTRIBUTING.md +19 -8
- data/Gemfile +5 -9
- data/LICENSE +1 -1
- data/MIGRATING-ES.md +317 -0
- data/MIGRATING.md +375 -0
- data/NEWS +184 -31
- data/README.md +371 -201
- data/RELEASING.md +17 -0
- data/Rakefile +2 -2
- data/UPGRADING +12 -9
- data/features/basic_integration.feature +10 -6
- data/features/migration.feature +0 -24
- data/features/step_definitions/attachment_steps.rb +41 -35
- data/features/step_definitions/html_steps.rb +2 -2
- data/features/step_definitions/rails_steps.rb +39 -38
- data/features/step_definitions/s3_steps.rb +2 -2
- data/features/step_definitions/web_steps.rb +1 -103
- data/features/support/env.rb +1 -0
- data/features/support/file_helpers.rb +2 -2
- data/features/support/paths.rb +1 -1
- data/features/support/rails.rb +0 -24
- data/gemfiles/4.2.gemfile +6 -8
- data/gemfiles/5.0.gemfile +17 -0
- data/lib/generators/paperclip/paperclip_generator.rb +9 -1
- data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +1 -1
- data/lib/paperclip/attachment.rb +51 -26
- data/lib/paperclip/attachment_registry.rb +3 -2
- data/lib/paperclip/callbacks.rb +8 -6
- data/lib/paperclip/content_type_detector.rb +27 -11
- data/lib/paperclip/errors.rb +3 -1
- data/lib/paperclip/file_command_content_type_detector.rb +6 -8
- data/lib/paperclip/filename_cleaner.rb +0 -1
- data/lib/paperclip/geometry_detector_factory.rb +3 -3
- data/lib/paperclip/geometry_parser_factory.rb +1 -1
- data/lib/paperclip/glue.rb +1 -1
- data/lib/paperclip/has_attached_file.rb +9 -2
- data/lib/paperclip/helpers.rb +15 -11
- data/lib/paperclip/interpolations/plural_cache.rb +6 -5
- data/lib/paperclip/interpolations.rb +24 -14
- data/lib/paperclip/io_adapters/abstract_adapter.rb +32 -4
- data/lib/paperclip/io_adapters/attachment_adapter.rb +17 -6
- data/lib/paperclip/io_adapters/data_uri_adapter.rb +8 -8
- data/lib/paperclip/io_adapters/empty_string_adapter.rb +5 -4
- data/lib/paperclip/io_adapters/file_adapter.rb +12 -6
- data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +8 -7
- data/lib/paperclip/io_adapters/identity_adapter.rb +12 -6
- data/lib/paperclip/io_adapters/nil_adapter.rb +8 -5
- data/lib/paperclip/io_adapters/registry.rb +6 -2
- data/lib/paperclip/io_adapters/stringio_adapter.rb +9 -6
- data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +10 -6
- data/lib/paperclip/io_adapters/uri_adapter.rb +43 -19
- data/lib/paperclip/logger.rb +1 -1
- data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +4 -4
- data/lib/paperclip/media_type_spoof_detector.rb +13 -9
- data/lib/paperclip/processor.rb +15 -6
- data/lib/paperclip/rails_environment.rb +25 -0
- data/lib/paperclip/schema.rb +4 -10
- data/lib/paperclip/storage/filesystem.rb +13 -2
- data/lib/paperclip/storage/fog.rb +33 -20
- data/lib/paperclip/storage/s3.rb +89 -70
- data/lib/paperclip/style.rb +0 -1
- data/lib/paperclip/thumbnail.rb +24 -12
- data/lib/paperclip/url_generator.rb +17 -13
- data/lib/paperclip/validators/attachment_size_validator.rb +1 -7
- data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +4 -0
- data/lib/paperclip/validators.rb +1 -1
- data/lib/paperclip/version.rb +3 -1
- data/lib/paperclip.rb +27 -13
- data/lib/tasks/paperclip.rake +33 -3
- data/paperclip.gemspec +18 -15
- data/spec/paperclip/attachment_definitions_spec.rb +1 -1
- data/spec/paperclip/attachment_processing_spec.rb +2 -5
- data/spec/paperclip/attachment_registry_spec.rb +84 -13
- data/spec/paperclip/attachment_spec.rb +147 -41
- data/spec/paperclip/content_type_detector_spec.rb +9 -2
- data/spec/paperclip/file_command_content_type_detector_spec.rb +15 -2
- data/spec/paperclip/filename_cleaner_spec.rb +0 -1
- data/spec/paperclip/geometry_spec.rb +1 -1
- data/spec/paperclip/glue_spec.rb +44 -0
- data/spec/paperclip/has_attached_file_spec.rb +24 -8
- data/spec/paperclip/integration_spec.rb +42 -5
- data/spec/paperclip/interpolations_spec.rb +21 -9
- data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +106 -23
- data/spec/paperclip/io_adapters/attachment_adapter_spec.rb +6 -3
- data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +7 -1
- data/spec/paperclip/io_adapters/file_adapter_spec.rb +6 -3
- data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +51 -14
- data/spec/paperclip/io_adapters/identity_adapter_spec.rb +1 -1
- data/spec/paperclip/io_adapters/registry_spec.rb +2 -2
- data/spec/paperclip/io_adapters/stringio_adapter_spec.rb +5 -1
- data/spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb +5 -5
- data/spec/paperclip/io_adapters/uri_adapter_spec.rb +126 -8
- data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +10 -0
- data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +1 -1
- data/spec/paperclip/media_type_spoof_detector_spec.rb +75 -11
- data/spec/paperclip/paperclip_spec.rb +15 -40
- data/spec/paperclip/plural_cache_spec.rb +17 -16
- data/spec/paperclip/processor_spec.rb +4 -4
- data/spec/paperclip/rails_environment_spec.rb +33 -0
- data/spec/paperclip/schema_spec.rb +46 -46
- data/spec/paperclip/storage/fog_spec.rb +63 -3
- data/spec/paperclip/storage/s3_live_spec.rb +20 -14
- data/spec/paperclip/storage/s3_spec.rb +400 -215
- data/spec/paperclip/style_spec.rb +0 -1
- data/spec/paperclip/tempfile_factory_spec.rb +4 -0
- data/spec/paperclip/tempfile_spec.rb +35 -0
- data/spec/paperclip/thumbnail_spec.rb +59 -38
- data/spec/paperclip/url_generator_spec.rb +55 -45
- data/spec/paperclip/validators/attachment_size_validator_spec.rb +26 -20
- data/spec/paperclip/validators_spec.rb +5 -5
- data/spec/spec_helper.rb +7 -1
- data/spec/support/assertions.rb +12 -1
- data/spec/support/fake_model.rb +4 -0
- data/spec/support/fixtures/empty.xlsx +0 -0
- data/spec/support/matchers/have_column.rb +11 -2
- data/spec/support/mock_attachment.rb +2 -0
- data/spec/support/mock_url_generator_builder.rb +2 -2
- data/spec/support/model_reconstruction.rb +11 -3
- data/spec/support/reporting.rb +11 -0
- metadata +110 -63
- data/RUNNING_TESTS.md +0 -4
- data/cucumber/paperclip_steps.rb +0 -6
- data/gemfiles/3.2.gemfile +0 -19
- data/gemfiles/4.0.gemfile +0 -19
- data/gemfiles/4.1.gemfile +0 -19
- data/lib/paperclip/locales/de.yml +0 -18
- data/lib/paperclip/locales/es.yml +0 -18
- data/lib/paperclip/locales/ja.yml +0 -18
- data/lib/paperclip/locales/pt-BR.yml +0 -18
- data/lib/paperclip/locales/zh-CN.yml +0 -18
- data/lib/paperclip/locales/zh-HK.yml +0 -18
- data/lib/paperclip/locales/zh-TW.yml +0 -18
- data/spec/support/mock_model.rb +0 -2
- data/spec/support/rails_helpers.rb +0 -7
data/README.md
CHANGED
@@ -1,9 +1,90 @@
|
|
1
1
|
Paperclip
|
2
2
|
=========
|
3
3
|
|
4
|
-
|
4
|
+
# Deprecated
|
5
5
|
|
6
|
-
Paperclip is
|
6
|
+
**[Paperclip is deprecated]**.
|
7
|
+
|
8
|
+
For new projects, we recommend Rails' own [ActiveStorage].
|
9
|
+
|
10
|
+
For existing projects, please consult and contribute to [the migration guide] ([en español]).
|
11
|
+
|
12
|
+
|
13
|
+
We will leave the Issues open as a discussion forum _only_. We do _not_
|
14
|
+
guarantee a response from us in the Issues.
|
15
|
+
|
16
|
+
We are no longer accepting pull requests _except_ pull requests against the
|
17
|
+
migration guide. All other pull requests will be closed without merging.
|
18
|
+
|
19
|
+
[Paperclip is deprecated]: https://robots.thoughtbot.com/closing-the-trombone
|
20
|
+
[ActiveStorage]: http://guides.rubyonrails.org/active_storage_overview.html
|
21
|
+
[the migration guide]: https://github.com/thoughtbot/paperclip/blob/master/MIGRATING.md
|
22
|
+
[en español]: https://github.com/thoughtbot/paperclip/blob/master/MIGRATING-ES.md
|
23
|
+
|
24
|
+
# Existing documentation
|
25
|
+
|
26
|
+
## Documentation valid for `master` branch
|
27
|
+
|
28
|
+
Please check the documentation for the paperclip version you are using:
|
29
|
+
https://github.com/thoughtbot/paperclip/releases
|
30
|
+
|
31
|
+
---
|
32
|
+
|
33
|
+
[![Build Status](https://secure.travis-ci.org/thoughtbot/paperclip.svg?branch=master)](http://travis-ci.org/thoughtbot/paperclip)
|
34
|
+
[![Dependency Status](https://gemnasium.com/thoughtbot/paperclip.svg?travis)](https://gemnasium.com/thoughtbot/paperclip)
|
35
|
+
[![Code Climate](https://codeclimate.com/github/thoughtbot/paperclip.svg)](https://codeclimate.com/github/thoughtbot/paperclip)
|
36
|
+
[![Inline docs](http://inch-ci.org/github/thoughtbot/paperclip.svg)](http://inch-ci.org/github/thoughtbot/paperclip)
|
37
|
+
[![Security](https://hakiri.io/github/thoughtbot/paperclip/master.svg)](https://hakiri.io/github/thoughtbot/paperclip/master)
|
38
|
+
|
39
|
+
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
40
|
+
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
41
|
+
|
42
|
+
- [Requirements](#requirements)
|
43
|
+
- [Ruby and Rails](#ruby-and-rails)
|
44
|
+
- [Image Processor](#image-processor)
|
45
|
+
- [`file`](#file)
|
46
|
+
- [Installation](#installation)
|
47
|
+
- [Quick Start](#quick-start)
|
48
|
+
- [Models](#models)
|
49
|
+
- [Migrations](#migrations)
|
50
|
+
- [Edit and New Views](#edit-and-new-views)
|
51
|
+
- [Edit and New Views with Simple Form](#edit-and-new-views-with-simple-form)
|
52
|
+
- [Controller](#controller)
|
53
|
+
- [View Helpers](#view-helpers)
|
54
|
+
- [Checking a File Exists](#checking-a-file-exists)
|
55
|
+
- [Deleting an Attachment](#deleting-an-attachment)
|
56
|
+
- [Usage](#usage)
|
57
|
+
- [Validations](#validations)
|
58
|
+
- [Internationalization (I18n)](#internationalization-i18n)
|
59
|
+
- [Security Validations](#security-validations)
|
60
|
+
- [Defaults](#defaults)
|
61
|
+
- [Migrations](#migrations-1)
|
62
|
+
- [Add Attachment Column To A Table](#add-attachment-column-to-a-table)
|
63
|
+
- [Schema Definition](#schema-definition)
|
64
|
+
- [Vintage Syntax](#vintage-syntax)
|
65
|
+
- [Storage](#storage)
|
66
|
+
- [Understanding Storage](#understanding-storage)
|
67
|
+
- [IO Adapters](#io-adapters)
|
68
|
+
- [Post Processing](#post-processing)
|
69
|
+
- [Custom Attachment Processors](#custom-attachment-processors)
|
70
|
+
- [Events](#events)
|
71
|
+
- [URI Obfuscation](#uri-obfuscation)
|
72
|
+
- [Checksum / Fingerprint](#checksum--fingerprint)
|
73
|
+
- [File Preservation for Soft-Delete](#file-preservation-for-soft-delete)
|
74
|
+
- [Dynamic Configuration](#dynamic-configuration)
|
75
|
+
- [Dynamic Styles:](#dynamic-styles)
|
76
|
+
- [Dynamic Processors:](#dynamic-processors)
|
77
|
+
- [Logging](#logging)
|
78
|
+
- [Deployment](#deployment)
|
79
|
+
- [Attachment Styles](#attachment-styles)
|
80
|
+
- [Testing](#testing)
|
81
|
+
- [Contributing](#contributing)
|
82
|
+
- [License](#license)
|
83
|
+
- [About thoughtbot](#about-thoughtbot)
|
84
|
+
|
85
|
+
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
86
|
+
|
87
|
+
Paperclip is intended as an easy file attachment library for ActiveRecord. The
|
7
88
|
intent behind it was to keep setup as easy as possible and to treat files as
|
8
89
|
much like other attributes as possible. This means they aren't saved to their
|
9
90
|
final locations on disk, nor are they deleted if set to nil, until
|
@@ -15,10 +96,10 @@ packages). Attached files are saved to the filesystem and referenced in the
|
|
15
96
|
browser by an easily understandable specification, which has sensible and
|
16
97
|
useful defaults.
|
17
98
|
|
18
|
-
See the documentation for `has_attached_file` in [`Paperclip::ClassMethods`](http://rubydoc.info/gems/paperclip/Paperclip/ClassMethods) for
|
99
|
+
See the documentation for `has_attached_file` in [`Paperclip::ClassMethods`](http://www.rubydoc.info/gems/paperclip/Paperclip/ClassMethods) for
|
19
100
|
more detailed options.
|
20
101
|
|
21
|
-
The complete [RDoc](http://
|
102
|
+
The complete [RDoc](http://www.rubydoc.info/gems/paperclip) is online.
|
22
103
|
|
23
104
|
---
|
24
105
|
|
@@ -27,9 +108,8 @@ Requirements
|
|
27
108
|
|
28
109
|
### Ruby and Rails
|
29
110
|
|
30
|
-
Paperclip now requires Ruby version **>= 1
|
31
|
-
|
32
|
-
If you're still on Ruby 1.8.7 or Ruby on Rails 2.3.x, you can still use Paperclip 2.7.x with your project. Also, everything in this README might not apply to your version of Paperclip, and you should read [the README for version 2.7](http://rubydoc.info/gems/paperclip/2.7.0) instead.
|
111
|
+
Paperclip now requires Ruby version **>= 2.1** and Rails version **>= 4.2**
|
112
|
+
(only if you're going to use Paperclip with Ruby on Rails).
|
33
113
|
|
34
114
|
### Image Processor
|
35
115
|
|
@@ -47,20 +127,25 @@ In development mode, you might add this line to `config/environments/development
|
|
47
127
|
Paperclip.options[:command_path] = "/usr/local/bin/"
|
48
128
|
```
|
49
129
|
|
50
|
-
If you're on Mac OS X, you'll want to run the following with Homebrew:
|
130
|
+
If you're on Mac OS X, you'll want to run the following with [Homebrew](http://www.brew.sh):
|
51
131
|
|
52
132
|
brew install imagemagick
|
53
133
|
|
54
134
|
If you are dealing with pdf uploads or running the test suite, you'll also need
|
55
|
-
|
135
|
+
to install GhostScript. On Mac OS X, you can also install that using Homebrew:
|
56
136
|
|
57
137
|
brew install gs
|
58
138
|
|
139
|
+
If you are on Ubuntu (or any Debian base Linux distribution), you'll want to run
|
140
|
+
the following with apt-get:
|
141
|
+
|
142
|
+
sudo apt-get install imagemagick -y
|
143
|
+
|
59
144
|
### `file`
|
60
145
|
|
61
|
-
The Unix [`file` command](
|
62
|
-
This utility isn't available in Windows, but comes bundled with Ruby [Devkit](https://github.com/oneclick/rubyinstaller/wiki/Development-Kit),
|
63
|
-
so Windows users must make sure that the devkit is installed and added to system `PATH`.
|
146
|
+
The Unix [`file` command](https://en.wikipedia.org/wiki/File_(command)) is required for content-type checking.
|
147
|
+
This utility isn't available in Windows, but comes bundled with Ruby [Devkit](https://github.com/oneclick/rubyinstaller/wiki/Development-Kit),
|
148
|
+
so Windows users must make sure that the devkit is installed and added to the system `PATH`.
|
64
149
|
|
65
150
|
**Manual Installation**
|
66
151
|
|
@@ -70,21 +155,21 @@ To manually install, you should perform the following:
|
|
70
155
|
|
71
156
|
> **Download & install `file` from [this URL](http://gnuwin32.sourceforge.net/packages/file.htm)**
|
72
157
|
|
73
|
-
To test, you can use the
|
158
|
+
To test, you can use the image below:
|
74
159
|
![untitled](https://cloud.githubusercontent.com/assets/1104431/4524452/a1f8cce4-4d44-11e4-872e-17adb96f79c9.png)
|
75
160
|
|
76
|
-
Next, you need to integrate with your environment -
|
161
|
+
Next, you need to integrate with your environment - preferably through the `PATH` variable, or by changing your `config/environments/development.rb` file
|
77
162
|
|
78
163
|
**PATH**
|
79
164
|
|
80
165
|
1. Click "Start"
|
81
166
|
2. On "Computer", right-click and select "Properties"
|
82
|
-
3. In
|
167
|
+
3. In Properties, select "Advanced System Settings"
|
83
168
|
4. Click the "Environment Variables" button
|
84
169
|
5. Locate the "PATH" var - at the end, add the path to your newly installed `file.exe` (typically `C:\Program Files (x86)\GnuWin32\bin`)
|
85
170
|
6. Restart any CMD shells you have open & see if it works
|
86
171
|
|
87
|
-
OR
|
172
|
+
OR
|
88
173
|
|
89
174
|
**Environment**
|
90
175
|
|
@@ -92,7 +177,7 @@ OR
|
|
92
177
|
2. Add the following line: `Paperclip.options[:command_path] = 'C:\Program Files (x86)\GnuWin32\bin'`
|
93
178
|
3. Restart your Rails server
|
94
179
|
|
95
|
-
Either of these methods will give your Rails setup access to the `file.exe` functionality,
|
180
|
+
Either of these methods will give your Rails setup access to the `file.exe` functionality, thus providing the ability to check the contents of a file (fixing the spoofing problem)
|
96
181
|
|
97
182
|
---
|
98
183
|
|
@@ -104,24 +189,18 @@ Paperclip is distributed as a gem, which is how it should be used in your app.
|
|
104
189
|
Include the gem in your Gemfile:
|
105
190
|
|
106
191
|
```ruby
|
107
|
-
gem "paperclip", "~>
|
108
|
-
```
|
109
|
-
|
110
|
-
If you're still using Rails 2.3.x, you should do this instead:
|
111
|
-
|
112
|
-
```ruby
|
113
|
-
gem "paperclip", "~> 2.7"
|
192
|
+
gem "paperclip", "~> 6.0.0"
|
114
193
|
```
|
115
194
|
|
116
195
|
Or, if you want to get the latest, you can get master from the main paperclip repository:
|
117
196
|
|
118
197
|
```ruby
|
119
|
-
gem "paperclip", :
|
198
|
+
gem "paperclip", git: "git://github.com/thoughtbot/paperclip.git"
|
120
199
|
```
|
121
200
|
|
122
201
|
If you're trying to use features that don't seem to be in the latest released gem, but are
|
123
202
|
mentioned in this README, then you probably need to specify the master branch if you want to
|
124
|
-
use them. This README is probably ahead of the latest released version
|
203
|
+
use them. This README is probably ahead of the latest released version if you're reading it
|
125
204
|
on GitHub.
|
126
205
|
|
127
206
|
For Non-Rails usage:
|
@@ -140,64 +219,54 @@ Quick Start
|
|
140
219
|
|
141
220
|
### Models
|
142
221
|
|
143
|
-
**Rails 3**
|
144
|
-
|
145
|
-
```ruby
|
146
|
-
class User < ActiveRecord::Base
|
147
|
-
attr_accessible :avatar
|
148
|
-
has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
|
149
|
-
validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
|
150
|
-
end
|
151
|
-
```
|
152
|
-
|
153
|
-
**Rails 4**
|
154
|
-
|
155
222
|
```ruby
|
156
223
|
class User < ActiveRecord::Base
|
157
|
-
has_attached_file :avatar, :
|
158
|
-
validates_attachment_content_type :avatar, :
|
224
|
+
has_attached_file :avatar, styles: { medium: "300x300>", thumb: "100x100>" }, default_url: "/images/:style/missing.png"
|
225
|
+
validates_attachment_content_type :avatar, content_type: /\Aimage\/.*\z/
|
159
226
|
end
|
160
227
|
```
|
161
228
|
|
162
229
|
### Migrations
|
163
230
|
|
231
|
+
|
232
|
+
Assuming you have a `users` table, add an `avatar` column to the `users` table:
|
164
233
|
```ruby
|
165
234
|
class AddAvatarColumnsToUsers < ActiveRecord::Migration
|
166
|
-
def
|
235
|
+
def up
|
167
236
|
add_attachment :users, :avatar
|
168
237
|
end
|
169
238
|
|
170
|
-
def
|
239
|
+
def down
|
171
240
|
remove_attachment :users, :avatar
|
172
241
|
end
|
173
242
|
end
|
174
243
|
```
|
175
244
|
|
176
|
-
(Or you can use migration generator: `rails generate paperclip user avatar`)
|
245
|
+
(Or you can use the Rails migration generator: `rails generate paperclip user avatar`)
|
177
246
|
|
178
247
|
### Edit and New Views
|
179
|
-
|
248
|
+
Make sure you have corresponding methods in your controller:
|
180
249
|
```erb
|
181
|
-
<%= form_for @user, :
|
250
|
+
<%= form_for @user, url: users_path, html: { multipart: true } do |form| %>
|
182
251
|
<%= form.file_field :avatar %>
|
252
|
+
<%= form.submit %>
|
183
253
|
<% end %>
|
184
254
|
```
|
185
255
|
|
186
|
-
###
|
187
|
-
|
188
|
-
**Rails 3**
|
256
|
+
### Edit and New Views with [Simple Form](https://github.com/plataformatec/simple_form)
|
189
257
|
|
190
|
-
```
|
191
|
-
|
192
|
-
|
193
|
-
|
258
|
+
```erb
|
259
|
+
<%= simple_form_for @user, url: users_path do |form| %>
|
260
|
+
<%= form.input :avatar, as: :file %>
|
261
|
+
<%= form.submit %>
|
262
|
+
<% end %>
|
194
263
|
```
|
195
264
|
|
196
|
-
|
265
|
+
### Controller
|
197
266
|
|
198
267
|
```ruby
|
199
268
|
def create
|
200
|
-
@user = User.create(
|
269
|
+
@user = User.create(user_params)
|
201
270
|
end
|
202
271
|
|
203
272
|
private
|
@@ -210,14 +279,24 @@ def user_params
|
|
210
279
|
end
|
211
280
|
```
|
212
281
|
|
213
|
-
###
|
214
|
-
|
282
|
+
### View Helpers
|
283
|
+
Add these to the view where you want your images displayed:
|
215
284
|
```erb
|
216
285
|
<%= image_tag @user.avatar.url %>
|
217
286
|
<%= image_tag @user.avatar.url(:medium) %>
|
218
287
|
<%= image_tag @user.avatar.url(:thumb) %>
|
219
288
|
```
|
220
289
|
|
290
|
+
### Checking a File Exists
|
291
|
+
|
292
|
+
There are two methods for checking if a file exists:
|
293
|
+
|
294
|
+
- `file?` and `present?` checks if the `_file_name` field is populated
|
295
|
+
- `exists?` checks if the file exists (will perform a TCP connection if stored in the cloud)
|
296
|
+
|
297
|
+
Keep this in mind if you are checking if files are present in a loop. The first
|
298
|
+
version is significantly more performant, but has different semantics.
|
299
|
+
|
221
300
|
### Deleting an Attachment
|
222
301
|
|
223
302
|
Set the attribute to `nil` and save.
|
@@ -231,7 +310,7 @@ Set the attribute to `nil` and save.
|
|
231
310
|
Usage
|
232
311
|
-----
|
233
312
|
|
234
|
-
The basics of
|
313
|
+
The basics of Paperclip are quite simple: Declare that your model has an
|
235
314
|
attachment with the `has_attached_file` method, and give it a name.
|
236
315
|
|
237
316
|
Paperclip will wrap up to four attributes (all prefixed with that attachment's name,
|
@@ -243,12 +322,12 @@ friendly front end. These attributes are:
|
|
243
322
|
* `<attachment>_content_type`
|
244
323
|
* `<attachment>_updated_at`
|
245
324
|
|
246
|
-
By default, only `<attachment>_file_name` is required for
|
325
|
+
By default, only `<attachment>_file_name` is required for Paperclip to operate.
|
247
326
|
You'll need to add `<attachment>_content_type` in case you want to use content type
|
248
327
|
validation.
|
249
328
|
|
250
|
-
More information about the options to `has_attached_file` is available in the
|
251
|
-
documentation of [`Paperclip::ClassMethods`](http://rubydoc.info/gems/paperclip/Paperclip/ClassMethods).
|
329
|
+
More information about the options passed to `has_attached_file` is available in the
|
330
|
+
documentation of [`Paperclip::ClassMethods`](http://www.rubydoc.info/gems/paperclip/Paperclip/ClassMethods).
|
252
331
|
|
253
332
|
Validations
|
254
333
|
-----------
|
@@ -262,9 +341,9 @@ For validations, Paperclip introduces several validators to validate your attach
|
|
262
341
|
Example Usage:
|
263
342
|
|
264
343
|
```ruby
|
265
|
-
validates :avatar, :
|
266
|
-
validates_with AttachmentPresenceValidator, :
|
267
|
-
validates_with AttachmentSizeValidator, :
|
344
|
+
validates :avatar, attachment_presence: true
|
345
|
+
validates_with AttachmentPresenceValidator, attributes: :avatar
|
346
|
+
validates_with AttachmentSizeValidator, attributes: :avatar, less_than: 1.megabytes
|
268
347
|
|
269
348
|
```
|
270
349
|
|
@@ -283,18 +362,18 @@ validates_attachment_presence :avatar
|
|
283
362
|
Lastly, you can also define multiple validations on a single attachment using `validates_attachment`:
|
284
363
|
|
285
364
|
```ruby
|
286
|
-
validates_attachment :avatar, :
|
287
|
-
|
288
|
-
:
|
365
|
+
validates_attachment :avatar, presence: true,
|
366
|
+
content_type: "image/jpeg",
|
367
|
+
size: { in: 0..10.kilobytes }
|
289
368
|
```
|
290
369
|
|
291
|
-
_NOTE: Post
|
292
|
-
according to the validations. Your callbacks and processors will
|
370
|
+
_NOTE: Post-processing will not even **start** if the attachment is not valid
|
371
|
+
according to the validations. Your callbacks and processors will **only** be
|
293
372
|
called with valid attachments._
|
294
373
|
|
295
374
|
```ruby
|
296
375
|
class Message < ActiveRecord::Base
|
297
|
-
has_attached_file :asset, styles: {thumb: "100x100#"}
|
376
|
+
has_attached_file :asset, styles: { thumb: "100x100#" }
|
298
377
|
|
299
378
|
before_post_process :skip_for_audio
|
300
379
|
|
@@ -310,8 +389,8 @@ afterwards, then assign manually:
|
|
310
389
|
|
311
390
|
```ruby
|
312
391
|
class Book < ActiveRecord::Base
|
313
|
-
has_attached_file :document, styles: {thumbnail: "60x60#"}
|
314
|
-
validates_attachment :document, content_type:
|
392
|
+
has_attached_file :document, styles: { thumbnail: "60x60#" }
|
393
|
+
validates_attachment :document, content_type: "application/pdf"
|
315
394
|
validates_something_else # Other validations that conflict with Paperclip's
|
316
395
|
end
|
317
396
|
|
@@ -343,7 +422,7 @@ image-y ones:
|
|
343
422
|
|
344
423
|
```ruby
|
345
424
|
validates_attachment :avatar,
|
346
|
-
|
425
|
+
content_type: ["image/jpeg", "image/gif", "image/png"]
|
347
426
|
```
|
348
427
|
|
349
428
|
`Paperclip::ContentTypeDetector` will attempt to match a file's extension to an
|
@@ -351,6 +430,12 @@ inferred content_type, regardless of the actual contents of the file.
|
|
351
430
|
|
352
431
|
---
|
353
432
|
|
433
|
+
Internationalization (I18n)
|
434
|
+
---------------------------
|
435
|
+
|
436
|
+
For using or adding locale files in different languages, check the project
|
437
|
+
https://github.com/thoughtbot/paperclip-i18n.
|
438
|
+
|
354
439
|
Security Validations
|
355
440
|
====================
|
356
441
|
|
@@ -367,9 +452,9 @@ do this.
|
|
367
452
|
class ActiveRecord::Base
|
368
453
|
has_attached_file :avatar
|
369
454
|
# Validate content type
|
370
|
-
validates_attachment_content_type :avatar, :
|
455
|
+
validates_attachment_content_type :avatar, content_type: /\Aimage/
|
371
456
|
# Validate filename
|
372
|
-
validates_attachment_file_name :avatar, :
|
457
|
+
validates_attachment_file_name :avatar, matches: [/png\z/, /jpe?g\z/]
|
373
458
|
# Explicitly do not validate
|
374
459
|
do_not_validate_attachment_file_type :avatar
|
375
460
|
end
|
@@ -382,48 +467,47 @@ NOTE: Also starting at version 4.0.0, Paperclip has another validation that
|
|
382
467
|
cannot be turned off. This validation will prevent content type spoofing. That
|
383
468
|
is, uploading a PHP document (for example) as part of the EXIF tags of a
|
384
469
|
well-formed JPEG. This check is limited to the media type (the first part of the
|
385
|
-
MIME type, so, 'text' in
|
470
|
+
MIME type, so, 'text' in `text/plain`). This will prevent HTML documents from
|
386
471
|
being uploaded as JPEGs, but will not prevent GIFs from being uploaded with a
|
387
|
-
|
388
|
-
will not cause
|
472
|
+
`.jpg` extension. This validation will only add validation errors to the form. It
|
473
|
+
will not cause errors to be raised.
|
389
474
|
|
390
|
-
This can sometimes cause false validation errors in applications that use custom
|
475
|
+
This can sometimes cause false validation errors in applications that use custom
|
391
476
|
file extensions. In these cases you may wish to add your custom extension to the
|
392
|
-
list of
|
393
|
-
gem:
|
477
|
+
list of content type mappings by creating `config/initializers/paperclip.rb`:
|
394
478
|
|
395
479
|
```ruby
|
396
|
-
# Allow ".foo" as an extension for files with the
|
397
|
-
|
398
|
-
|
399
|
-
|
480
|
+
# Allow ".foo" as an extension for files with the MIME type "text/plain".
|
481
|
+
Paperclip.options[:content_type_mappings] = {
|
482
|
+
foo: %w(text/plain)
|
483
|
+
}
|
400
484
|
```
|
401
485
|
|
402
486
|
---
|
403
487
|
|
404
488
|
Defaults
|
405
489
|
--------
|
406
|
-
Global defaults for all your
|
490
|
+
Global defaults for all your Paperclip attachments can be defined by changing the Paperclip::Attachment.default_options Hash. This can be useful for setting your default storage settings per example so you won't have to define them in every `has_attached_file` definition.
|
407
491
|
|
408
|
-
If you're using Rails you can define a Hash with default options in config/application.rb or in any of the config/environments/*.rb files on config.paperclip_defaults
|
492
|
+
If you're using Rails, you can define a Hash with default options in `config/application.rb` or in any of the `config/environments/*.rb` files on config.paperclip_defaults. These will get merged into `Paperclip::Attachment.default_options` as your Rails app boots. An example:
|
409
493
|
|
410
494
|
```ruby
|
411
495
|
module YourApp
|
412
496
|
class Application < Rails::Application
|
413
497
|
# Other code...
|
414
498
|
|
415
|
-
config.paperclip_defaults = {:
|
499
|
+
config.paperclip_defaults = { storage: :fog, fog_credentials: { provider: "Local", local_root: "#{Rails.root}/public"}, fog_directory: "", fog_host: "localhost"}
|
416
500
|
end
|
417
501
|
end
|
418
502
|
```
|
419
503
|
|
420
|
-
Another option is to directly modify the Paperclip::Attachment.default_options Hash
|
504
|
+
Another option is to directly modify the `Paperclip::Attachment.default_options` Hash - this method works for non-Rails applications or is an option if you prefer to place the Paperclip default settings in an initializer.
|
421
505
|
|
422
506
|
An example Rails initializer would look something like this:
|
423
507
|
|
424
508
|
```ruby
|
425
509
|
Paperclip::Attachment.default_options[:storage] = :fog
|
426
|
-
Paperclip::Attachment.default_options[:fog_credentials] = {:
|
510
|
+
Paperclip::Attachment.default_options[:fog_credentials] = { provider: "Local", local_root: "#{Rails.root}/public"}
|
427
511
|
Paperclip::Attachment.default_options[:fog_directory] = ""
|
428
512
|
Paperclip::Attachment.default_options[:fog_host] = "http://localhost:3000"
|
429
513
|
```
|
@@ -432,25 +516,32 @@ Paperclip::Attachment.default_options[:fog_host] = "http://localhost:3000"
|
|
432
516
|
Migrations
|
433
517
|
----------
|
434
518
|
|
435
|
-
Paperclip defines several migration methods which can be used to create necessary columns in your
|
436
|
-
model. There are two types of
|
519
|
+
Paperclip defines several migration methods which can be used to create the necessary columns in your
|
520
|
+
model. There are two types of helper methods to aid in this, as follows:
|
521
|
+
|
522
|
+
### Add Attachment Column To A Table
|
437
523
|
|
438
|
-
|
524
|
+
The `attachment` helper can be used when creating a table:
|
439
525
|
|
440
526
|
```ruby
|
441
|
-
class
|
442
|
-
def
|
527
|
+
class CreateUsersWithAttachments < ActiveRecord::Migration
|
528
|
+
def up
|
443
529
|
create_table :users do |t|
|
444
530
|
t.attachment :avatar
|
445
531
|
end
|
446
532
|
end
|
533
|
+
|
534
|
+
# This is assuming you are only using the users table for Paperclip attachment. Drop with care!
|
535
|
+
def down
|
536
|
+
drop_table :users
|
537
|
+
end
|
447
538
|
end
|
448
539
|
```
|
449
540
|
|
450
|
-
|
541
|
+
You can also use the `change` method, instead of the `up`/`down` combination above, as shown below:
|
451
542
|
|
452
543
|
```ruby
|
453
|
-
class
|
544
|
+
class CreateUsersWithAttachments < ActiveRecord::Migration
|
454
545
|
def change
|
455
546
|
create_table :users do |t|
|
456
547
|
t.attachment :avatar
|
@@ -461,31 +552,33 @@ end
|
|
461
552
|
|
462
553
|
### Schema Definition
|
463
554
|
|
555
|
+
Alternatively, the `add_attachment` and `remove_attachment` methods can be used to add new Paperclip columns to an existing table:
|
556
|
+
|
464
557
|
```ruby
|
465
|
-
class
|
466
|
-
def
|
558
|
+
class AddAttachmentColumnsToUsers < ActiveRecord::Migration
|
559
|
+
def up
|
467
560
|
add_attachment :users, :avatar
|
468
561
|
end
|
469
562
|
|
470
|
-
def
|
563
|
+
def down
|
471
564
|
remove_attachment :users, :avatar
|
472
565
|
end
|
473
566
|
end
|
474
567
|
```
|
475
568
|
|
476
|
-
|
569
|
+
Or you can do this with the `change` method:
|
477
570
|
|
478
571
|
```ruby
|
479
|
-
class
|
572
|
+
class AddAttachmentColumnsToUsers < ActiveRecord::Migration
|
480
573
|
def change
|
481
574
|
add_attachment :users, :avatar
|
482
575
|
end
|
483
576
|
end
|
484
577
|
```
|
485
578
|
|
486
|
-
### Vintage
|
579
|
+
### Vintage Syntax
|
487
580
|
|
488
|
-
Vintage syntax (such as `t.has_attached_file` and `drop_attached_file`)
|
581
|
+
Vintage syntax (such as `t.has_attached_file` and `drop_attached_file`) is still supported in
|
489
582
|
Paperclip 3.x, but you're advised to update those migration files to use this new syntax.
|
490
583
|
|
491
584
|
---
|
@@ -496,12 +589,13 @@ Storage
|
|
496
589
|
Paperclip ships with 3 storage adapters:
|
497
590
|
|
498
591
|
* File Storage
|
499
|
-
* S3 Storage (via `aws-sdk`)
|
592
|
+
* S3 Storage (via `aws-sdk-s3`)
|
500
593
|
* Fog Storage
|
501
594
|
|
502
595
|
If you would like to use Paperclip with another storage, you can install these
|
503
596
|
gems along side with Paperclip:
|
504
597
|
|
598
|
+
* [paperclip-azure](https://github.com/supportify/paperclip-azure)
|
505
599
|
* [paperclip-azure-storage](https://github.com/gmontard/paperclip-azure-storage)
|
506
600
|
* [paperclip-dropbox](https://github.com/janko-m/paperclip-dropbox)
|
507
601
|
|
@@ -510,9 +604,9 @@ gems along side with Paperclip:
|
|
510
604
|
The files that are assigned as attachments are, by default, placed in the
|
511
605
|
directory specified by the `:path` option to `has_attached_file`. By default, this
|
512
606
|
location is `:rails_root/public/system/:class/:attachment/:id_partition/:style/:filename`.
|
513
|
-
This location was chosen because on standard Capistrano deployments, the
|
514
|
-
`public/system` directory
|
515
|
-
|
607
|
+
This location was chosen because, on standard Capistrano deployments, the
|
608
|
+
`public/system` directory can be symlinked to the app's shared directory, meaning it
|
609
|
+
survives between deployments. For example, using that `:path`, you may have a
|
516
610
|
file at
|
517
611
|
|
518
612
|
/data/myapp/releases/20081229172410/public/system/users/avatar/000/000/013/small/my_pic.png
|
@@ -521,15 +615,15 @@ _**NOTE**: This is a change from previous versions of Paperclip, but is overall
|
|
521
615
|
safer choice for the default file store._
|
522
616
|
|
523
617
|
You may also choose to store your files using Amazon's S3 service. To do so, include
|
524
|
-
the `aws-sdk` gem in your Gemfile:
|
618
|
+
the `aws-sdk-s3` gem in your Gemfile:
|
525
619
|
|
526
620
|
```ruby
|
527
|
-
gem 'aws-sdk'
|
621
|
+
gem 'aws-sdk-s3'
|
528
622
|
```
|
529
623
|
|
530
624
|
And then you can specify using S3 from `has_attached_file`.
|
531
625
|
You can find more information about configuring and using S3 storage in
|
532
|
-
[the `Paperclip::Storage::S3` documentation](http://rubydoc.info/gems/paperclip/Paperclip/Storage/S3).
|
626
|
+
[the `Paperclip::Storage::S3` documentation](http://www.rubydoc.info/gems/paperclip/Paperclip/Storage/S3).
|
533
627
|
|
534
628
|
Files on the local filesystem (and in the Rails app's public directory) will be
|
535
629
|
available to the internet at large. If you require access control, it's
|
@@ -540,64 +634,121 @@ variables.
|
|
540
634
|
|
541
635
|
---
|
542
636
|
|
637
|
+
IO Adapters
|
638
|
+
-----------
|
639
|
+
|
640
|
+
When a file is uploaded or attached, it can be in one of a few different input
|
641
|
+
forms, from Rails' UploadedFile object to a StringIO to a Tempfile or even a
|
642
|
+
simple String that is a URL that points to an image.
|
643
|
+
|
644
|
+
Paperclip will accept, by default, many of these sources. It also is capable of
|
645
|
+
handling even more with a little configuration. The IO Adapters that handle
|
646
|
+
images from non-local sources are not enabled by default. They can be enabled by
|
647
|
+
adding a line similar to the following into `config/initializers/paperclip.rb`:
|
648
|
+
|
649
|
+
```ruby
|
650
|
+
Paperclip::DataUriAdapter.register
|
651
|
+
```
|
652
|
+
|
653
|
+
It's best to only enable a remote-loading adapter if you need it. Otherwise
|
654
|
+
there's a chance that someone can gain insight into your internal network
|
655
|
+
structure using it as a vector.
|
656
|
+
|
657
|
+
The following adapters are *not* loaded by default:
|
658
|
+
|
659
|
+
* `Paperclip::UriAdapter` - which accepts a `URI` instance.
|
660
|
+
* `Paperclip::HttpUrlProxyAdapter` - which accepts a `http` string.
|
661
|
+
* `Paperclip::DataUriAdapter` - which accepts a Base64-encoded `data:` string.
|
662
|
+
|
663
|
+
---
|
664
|
+
|
543
665
|
Post Processing
|
544
666
|
---------------
|
545
667
|
|
546
668
|
Paperclip supports an extensible selection of post-processors. When you define
|
547
669
|
a set of styles for an attachment, by default it is expected that those
|
548
|
-
"styles" are actually "thumbnails"
|
549
|
-
|
550
|
-
|
551
|
-
|
552
|
-
|
553
|
-
|
554
|
-
|
670
|
+
"styles" are actually "thumbnails." These are processed by
|
671
|
+
`Paperclip::Thumbnail`. For backward compatibility reasons you can pass either
|
672
|
+
a single geometry string, or an array containing a geometry and a format that
|
673
|
+
the file will be converted to, like so:
|
674
|
+
|
675
|
+
```ruby
|
676
|
+
has_attached_file :avatar, styles: { thumb: ["32x32#", :png] }
|
677
|
+
```
|
678
|
+
|
679
|
+
This will convert the "thumb" style to a 32x32 square in PNG format, regardless
|
680
|
+
of what was uploaded. If the format is not specified, it is kept the same (e.g.
|
681
|
+
JPGs will remain JPGs). `Paperclip::Thumbnail` uses ImageMagick to process
|
682
|
+
images; [ImageMagick's geometry documentation](http://www.imagemagick.org/script/command-line-processing.php#geometry)
|
683
|
+
has more information on the accepted style formats.
|
684
|
+
|
685
|
+
For more fine-grained control of the conversion process, `source_file_options` and `convert_options` can be used to pass flags and settings directly to ImageMagick's powerful Convert tool, [documented here](https://www.imagemagick.org/script/convert.php). For example:
|
555
686
|
|
556
687
|
```ruby
|
557
|
-
has_attached_file :
|
558
|
-
|
688
|
+
has_attached_file :image, styles: { regular: ['800x800>', :png]},
|
689
|
+
source_file_options: { regular: "-density 96 -depth 8 -quality 85" },
|
690
|
+
convert_options: { regular: "-posterize 3"}
|
559
691
|
```
|
560
692
|
|
561
|
-
|
562
|
-
hash "{ :quality => :better }" passed to it along with the uploaded file. For
|
563
|
-
more information about defining processors, see Paperclip::Processor.
|
693
|
+
ImageMagick supports a number of environment variables for controlling its resource limits. For example, you can enforce memory or execution time limits by setting the following variables in your application's process environment:
|
564
694
|
|
565
|
-
|
566
|
-
|
567
|
-
|
695
|
+
* `MAGICK_MEMORY_LIMIT=128MiB`
|
696
|
+
* `MAGICK_MAP_LIMIT=64MiB`
|
697
|
+
* `MAGICK_TIME_LIMIT=30`
|
698
|
+
|
699
|
+
For a full list of variables and description, see [ImageMagick's resources documentation](http://www.imagemagick.org/script/resources.php).
|
700
|
+
|
701
|
+
---
|
702
|
+
|
703
|
+
Custom Attachment Processors
|
704
|
+
-------
|
705
|
+
|
706
|
+
You can write your own custom attachment processors to carry out tasks like
|
707
|
+
adding watermarks, compressing images, or encrypting files. Custom processors
|
708
|
+
must be defined within the `Paperclip` module, inherit from
|
709
|
+
`Paperclip::Processor` (see [`lib/paperclip/processor.rb`](https://github.com/thoughtbot/paperclip/blob/master/lib/paperclip/processor.rb)),
|
710
|
+
and implement a `make` method that returns a `File`. All files in your Rails
|
711
|
+
app's `lib/paperclip` and `lib/paperclip_processors` directories will be
|
712
|
+
automatically loaded by Paperclip. Processors are specified using the
|
713
|
+
`:processors` option to `has_attached_file`:
|
568
714
|
|
569
715
|
```ruby
|
570
|
-
has_attached_file :
|
716
|
+
has_attached_file :scan, styles: { text: { quality: :better } },
|
717
|
+
processors: [:ocr]
|
571
718
|
```
|
572
719
|
|
573
|
-
This
|
574
|
-
|
575
|
-
jpgs will remain jpgs). For more information on the accepted style formats, see
|
576
|
-
[here](http://www.imagemagick.org/script/command-line-processing.php#geometry).
|
720
|
+
This would load the hypothetical class `Paperclip::Ocr`, and pass it the
|
721
|
+
options hash `{ quality: :better }`, along with the uploaded file.
|
577
722
|
|
578
723
|
Multiple processors can be specified, and they will be invoked in the order
|
579
|
-
they are defined in the
|
580
|
-
|
581
|
-
|
582
|
-
|
724
|
+
they are defined in the `:processors` array. Each successive processor is given
|
725
|
+
the result from the previous processor. All processors receive the same
|
726
|
+
parameters, which are defined in the `:styles` hash. For example, assuming we
|
727
|
+
had this definition:
|
583
728
|
|
584
729
|
```ruby
|
585
|
-
has_attached_file :scan, :
|
586
|
-
:
|
730
|
+
has_attached_file :scan, styles: { text: { quality: :better } },
|
731
|
+
processors: [:rotator, :ocr]
|
587
732
|
```
|
588
733
|
|
589
|
-
|
590
|
-
options
|
591
|
-
|
734
|
+
Both the `:rotator` processor and the `:ocr` processor would receive the
|
735
|
+
options `{ quality: :better }`. If a processor receives an option it doesn't
|
736
|
+
recognise, it's expected to ignore it.
|
592
737
|
|
593
738
|
_NOTE: Because processors operate by turning the original attachment into the
|
594
739
|
styles, no processors will be run if there are no styles defined._
|
595
740
|
|
596
741
|
If you're interested in caching your thumbnail's width, height and size in the
|
597
|
-
database, take a look at the [paperclip-meta](https://github.com/teeparham/paperclip-meta)
|
742
|
+
database, take a look at the [paperclip-meta](https://github.com/teeparham/paperclip-meta)
|
743
|
+
gem.
|
598
744
|
|
599
745
|
Also, if you're interested in generating the thumbnail on-the-fly, you might want
|
600
|
-
to look into the [attachment_on_the_fly](https://github.com/drpentode/Attachment-on-the-Fly)
|
746
|
+
to look into the [attachment_on_the_fly](https://github.com/drpentode/Attachment-on-the-Fly)
|
747
|
+
gem.
|
748
|
+
|
749
|
+
Paperclip's thumbnail generator (see [`lib/paperclip/thumbnail.rb`](lib/paperclip/thumbnail.rb))
|
750
|
+
is implemented as a processor, and may be a good reference for writing your own
|
751
|
+
processors.
|
601
752
|
|
602
753
|
---
|
603
754
|
|
@@ -615,13 +766,13 @@ normal ActiveRecord callbacks as possible, so if you return false (specifically
|
|
615
766
|
will halt. Returning false in an `after_filter` will not halt anything, but you
|
616
767
|
can access the model and the attachment if necessary.
|
617
768
|
|
618
|
-
_NOTE: Post processing will not even
|
619
|
-
according to the validations. Your callbacks and processors will
|
769
|
+
_NOTE: Post processing will not even **start** if the attachment is not valid
|
770
|
+
according to the validations. Your callbacks and processors will **only** be
|
620
771
|
called with valid attachments._
|
621
772
|
|
622
773
|
```ruby
|
623
774
|
class Message < ActiveRecord::Base
|
624
|
-
has_attached_file :asset, styles: {thumb: "100x100#"}
|
775
|
+
has_attached_file :asset, styles: { thumb: "100x100#" }
|
625
776
|
|
626
777
|
before_post_process :skip_for_audio
|
627
778
|
|
@@ -643,8 +794,8 @@ Example Usage:
|
|
643
794
|
|
644
795
|
```ruby
|
645
796
|
has_attached_file :avatar, {
|
646
|
-
:
|
647
|
-
:
|
797
|
+
url: "/system/:hash.:extension",
|
798
|
+
hash_secret: "longSecretString"
|
648
799
|
}
|
649
800
|
```
|
650
801
|
|
@@ -652,29 +803,40 @@ has_attached_file :avatar, {
|
|
652
803
|
The `:hash` interpolation will be replaced with a unique hash made up of whatever
|
653
804
|
is specified in `:hash_data`. The default value for `:hash_data` is `":class/:attachment/:id/:style/:updated_at"`.
|
654
805
|
|
655
|
-
`:hash_secret` is required
|
806
|
+
`:hash_secret` is required - an exception will be raised if `:hash` is used without `:hash_secret` present.
|
656
807
|
|
657
|
-
For more on this feature read the author's own explanation
|
808
|
+
For more on this feature, read [the author's own explanation](https://github.com/thoughtbot/paperclip/pull/416)
|
658
809
|
|
659
|
-
|
810
|
+
Checksum / Fingerprint
|
660
811
|
-------
|
661
812
|
|
662
|
-
A
|
813
|
+
A checksum of the original file assigned will be placed in the model if it
|
663
814
|
has an attribute named fingerprint. Following the user model migration example
|
664
|
-
above, the migration would look like the following
|
815
|
+
above, the migration would look like the following:
|
665
816
|
|
666
817
|
```ruby
|
667
818
|
class AddAvatarFingerprintColumnToUser < ActiveRecord::Migration
|
668
|
-
def
|
819
|
+
def up
|
669
820
|
add_column :users, :avatar_fingerprint, :string
|
670
821
|
end
|
671
822
|
|
672
|
-
def
|
823
|
+
def down
|
673
824
|
remove_column :users, :avatar_fingerprint
|
674
825
|
end
|
675
826
|
end
|
676
827
|
```
|
677
828
|
|
829
|
+
The algorithm can be specified using a configuration option; it defaults to MD5
|
830
|
+
for backwards compatibility with Paperclip 5 and earlier.
|
831
|
+
|
832
|
+
```ruby
|
833
|
+
has_attached_file :some_attachment, adapter_options: { hash_digest: Digest::SHA256 }
|
834
|
+
```
|
835
|
+
|
836
|
+
Run `CLASS=User ATTACHMENT=avatar rake paperclip:refresh:fingerprints` after
|
837
|
+
changing the digest on existing attachments to update the fingerprints in the
|
838
|
+
database.
|
839
|
+
|
678
840
|
File Preservation for Soft-Delete
|
679
841
|
-------
|
680
842
|
|
@@ -682,7 +844,7 @@ An option is available to preserve attachments in order to play nicely with soft
|
|
682
844
|
|
683
845
|
```ruby
|
684
846
|
has_attached_file :some_attachment, {
|
685
|
-
:
|
847
|
+
preserve_files: true,
|
686
848
|
}
|
687
849
|
```
|
688
850
|
|
@@ -690,25 +852,6 @@ This will prevent ```some_attachment``` from being wiped out when the model gets
|
|
690
852
|
|
691
853
|
---
|
692
854
|
|
693
|
-
Custom Attachment Processors
|
694
|
-
-------
|
695
|
-
|
696
|
-
Custom attachment processors can be implemented and their only requirement is
|
697
|
-
to inherit from `Paperclip::Processor` (see `lib/paperclip/processor.rb`).
|
698
|
-
For example, when `:styles` are specified for an image attachment, the
|
699
|
-
thumbnail processor (see `lib/paperclip/thumbnail.rb`) is loaded without having
|
700
|
-
to specify it as a `:processor` parameter to `has_attached_file`. When any
|
701
|
-
other processor is defined it must be called out in the `:processors`
|
702
|
-
parameter if it is to be applied to the attachment. The thumbnail processor
|
703
|
-
uses the imagemagick `convert` command to do the work of resizing image
|
704
|
-
thumbnails. It would be easy to create a custom processor that watermarks
|
705
|
-
an image using imagemagick's `composite` command. Following the
|
706
|
-
implementation pattern of the thumbnail processor would be a way to implement a
|
707
|
-
watermark processor. All kinds of attachment processors can be created;
|
708
|
-
a few utility examples would be compression and encryption processors.
|
709
|
-
|
710
|
-
---
|
711
|
-
|
712
855
|
Dynamic Configuration
|
713
856
|
---------------------
|
714
857
|
|
@@ -722,7 +865,7 @@ instances.
|
|
722
865
|
### Dynamic Styles:
|
723
866
|
|
724
867
|
Imagine a user model that had different styles based on the role of the user.
|
725
|
-
Perhaps some users are bosses (e.g. a User model instance responds to
|
868
|
+
Perhaps some users are bosses (e.g. a User model instance responds to `#boss?`)
|
726
869
|
and merit a bigger avatar thumbnail than regular users. The configuration to
|
727
870
|
determine what style parameters are to be used based on the user role might
|
728
871
|
look as follows where a boss will receive a `300x300` thumbnail otherwise a
|
@@ -730,7 +873,7 @@ look as follows where a boss will receive a `300x300` thumbnail otherwise a
|
|
730
873
|
|
731
874
|
```ruby
|
732
875
|
class User < ActiveRecord::Base
|
733
|
-
has_attached_file :avatar, :
|
876
|
+
has_attached_file :avatar, styles: lambda { |attachment| { thumb: (attachment.instance.boss? ? "300x300>" : "100x100>") } }
|
734
877
|
end
|
735
878
|
```
|
736
879
|
|
@@ -747,7 +890,7 @@ processors, where a defined `watermark` processor is invoked after the
|
|
747
890
|
|
748
891
|
```ruby
|
749
892
|
class User < ActiveRecord::Base
|
750
|
-
has_attached_file :avatar, :
|
893
|
+
has_attached_file :avatar, processors: lambda { |instance| instance.processors }
|
751
894
|
attr_accessor :processors
|
752
895
|
end
|
753
896
|
```
|
@@ -757,7 +900,7 @@ end
|
|
757
900
|
Logging
|
758
901
|
----------
|
759
902
|
|
760
|
-
By default Paperclip outputs logging according to your logger level. If you want to disable logging (e.g. during testing) add this
|
903
|
+
By default, Paperclip outputs logging according to your logger level. If you want to disable logging (e.g. during testing) add this into your environment's configuration:
|
761
904
|
```ruby
|
762
905
|
Your::Application.configure do
|
763
906
|
...
|
@@ -766,13 +909,23 @@ Your::Application.configure do
|
|
766
909
|
end
|
767
910
|
```
|
768
911
|
|
769
|
-
More information in the [rdocs](http://
|
912
|
+
More information in the [rdocs](http://www.rubydoc.info/github/thoughtbot/paperclip/Paperclip.options)
|
770
913
|
|
771
914
|
---
|
772
915
|
|
773
916
|
Deployment
|
774
917
|
----------
|
775
918
|
|
919
|
+
To make Capistrano symlink the `public/system` directory so that attachments
|
920
|
+
survive new deployments, set the `linked_dirs` option in your `config/deploy.rb`
|
921
|
+
file:
|
922
|
+
|
923
|
+
```ruby
|
924
|
+
set :linked_dirs, fetch(:linked_dirs, []).push('public/system')
|
925
|
+
```
|
926
|
+
|
927
|
+
### Attachment Styles
|
928
|
+
|
776
929
|
Paperclip is aware of new attachment styles you have added in previous deploys. The only thing you should do after each deployment is to call
|
777
930
|
`rake paperclip:refresh:missing_styles`. It will store current attachment styles in `RAILS_ROOT/public/system/paperclip_attachments.yml`
|
778
931
|
by default. You can change it by:
|
@@ -784,32 +937,36 @@ Paperclip.registered_attachments_styles_path = '/tmp/config/paperclip_attachment
|
|
784
937
|
Here is an example for Capistrano:
|
785
938
|
|
786
939
|
```ruby
|
787
|
-
namespace :
|
940
|
+
namespace :paperclip do
|
788
941
|
desc "build missing paperclip styles"
|
789
|
-
task :
|
942
|
+
task :build_missing_styles do
|
790
943
|
on roles(:app) do
|
791
|
-
|
944
|
+
within release_path do
|
945
|
+
with rails_env: fetch(:rails_env) do
|
946
|
+
execute :rake, "paperclip:refresh:missing_styles"
|
947
|
+
end
|
948
|
+
end
|
792
949
|
end
|
793
950
|
end
|
794
951
|
end
|
795
952
|
|
796
|
-
after("deploy:compile_assets", "
|
953
|
+
after("deploy:compile_assets", "paperclip:build_missing_styles")
|
797
954
|
```
|
798
955
|
|
799
956
|
Now you don't have to remember to refresh thumbnails in production every time you add a new style.
|
800
|
-
Unfortunately it does not work with dynamic styles - it just ignores them.
|
957
|
+
Unfortunately, it does not work with dynamic styles - it just ignores them.
|
801
958
|
|
802
959
|
If you already have a working app and don't want `rake paperclip:refresh:missing_styles` to refresh old pictures, you need to tell
|
803
960
|
Paperclip about existing styles. Simply create a `paperclip_attachments.yml` file by hand. For example:
|
804
961
|
|
805
962
|
```ruby
|
806
963
|
class User < ActiveRecord::Base
|
807
|
-
has_attached_file :avatar, :
|
964
|
+
has_attached_file :avatar, styles: { thumb: 'x100', croppable: '600x600>', big: '1000x1000>' }
|
808
965
|
end
|
809
966
|
|
810
967
|
class Book < ActiveRecord::Base
|
811
|
-
has_attached_file :cover, :
|
812
|
-
has_attached_file :sample, :
|
968
|
+
has_attached_file :cover, styles: { small: 'x100', large: '1000x1000>' }
|
969
|
+
has_attached_file :sample, styles: { thumb: 'x100' }
|
813
970
|
end
|
814
971
|
```
|
815
972
|
|
@@ -836,7 +993,7 @@ Testing
|
|
836
993
|
-------
|
837
994
|
|
838
995
|
Paperclip provides rspec-compatible matchers for testing attachments. See the
|
839
|
-
documentation on [Paperclip::Shoulda::Matchers](http://rubydoc.info/gems/paperclip/Paperclip/Shoulda/Matchers)
|
996
|
+
documentation on [Paperclip::Shoulda::Matchers](http://www.rubydoc.info/gems/paperclip/Paperclip/Shoulda/Matchers)
|
840
997
|
for more information.
|
841
998
|
|
842
999
|
**Parallel Tests**
|
@@ -855,12 +1012,12 @@ else
|
|
855
1012
|
end
|
856
1013
|
```
|
857
1014
|
|
858
|
-
The important part here being the inclusion of `ENV['TEST_ENV_NUMBER']`, or
|
1015
|
+
The important part here being the inclusion of `ENV['TEST_ENV_NUMBER']`, or a
|
859
1016
|
similar mechanism for whichever parallel testing library you use.
|
860
1017
|
|
861
1018
|
**Integration Tests**
|
862
1019
|
|
863
|
-
Using integration tests with
|
1020
|
+
Using integration tests with FactoryBot may save multiple copies of
|
864
1021
|
your test files within the app. To avoid this, specify a custom path in
|
865
1022
|
the `config/environments/test.rb` like so:
|
866
1023
|
|
@@ -876,6 +1033,17 @@ config.after(:suite) do
|
|
876
1033
|
FileUtils.rm_rf(Dir["#{Rails.root}/spec/test_files/"])
|
877
1034
|
end
|
878
1035
|
```
|
1036
|
+
|
1037
|
+
**Example of test configuration with Factory Bot**
|
1038
|
+
|
1039
|
+
|
1040
|
+
```ruby
|
1041
|
+
FactoryBot.define do
|
1042
|
+
factory :user do
|
1043
|
+
avatar { File.new("#{Rails.root}/spec/support/fixtures/image.jpg") }
|
1044
|
+
end
|
1045
|
+
end
|
1046
|
+
```
|
879
1047
|
---
|
880
1048
|
|
881
1049
|
Contributing
|
@@ -891,25 +1059,27 @@ guidelines:
|
|
891
1059
|
about writing tests for paperclip, please open a
|
892
1060
|
[GitHub issue](https://github.com/thoughtbot/paperclip/issues/new).
|
893
1061
|
|
894
|
-
Please see `CONTRIBUTING.md` for more details on contributing and running test.
|
1062
|
+
Please see [`CONTRIBUTING.md`](./CONTRIBUTING.md) for more details on contributing and running test.
|
895
1063
|
|
896
|
-
|
1064
|
+
Thank you to all [the contributors](https://github.com/thoughtbot/paperclip/graphs/contributors)!
|
897
1065
|
|
898
|
-
|
1066
|
+
License
|
899
1067
|
-------
|
900
1068
|
|
901
|
-
|
1069
|
+
Paperclip is Copyright © 2008-2017 thoughtbot, inc. It is free software, and may be
|
1070
|
+
redistributed under the terms specified in the MIT-LICENSE file.
|
902
1071
|
|
903
|
-
|
1072
|
+
About thoughtbot
|
1073
|
+
----------------
|
904
1074
|
|
905
|
-
|
1075
|
+
![thoughtbot](http://presskit.thoughtbot.com/images/thoughtbot-logo-for-readmes.svg)
|
906
1076
|
|
1077
|
+
Paperclip is maintained and funded by thoughtbot.
|
907
1078
|
The names and logos for thoughtbot are trademarks of thoughtbot, inc.
|
908
1079
|
|
909
|
-
|
910
|
-
|
911
|
-
|
912
|
-
-------
|
1080
|
+
We love open source software!
|
1081
|
+
See [our other projects][community] or
|
1082
|
+
[hire us][hire] to design, develop, and grow your product.
|
913
1083
|
|
914
|
-
|
915
|
-
|
1084
|
+
[community]: https://thoughtbot.com/community?utm_source=github
|
1085
|
+
[hire]: https://thoughtbot.com?utm_source=github
|