paperclip 4.2.2 → 6.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (141) hide show
  1. checksums.yaml +5 -5
  2. data/.codeclimate.yml +17 -0
  3. data/.github/issue_template.md +3 -0
  4. data/.hound.yml +1055 -0
  5. data/.rubocop.yml +1 -0
  6. data/.travis.yml +17 -15
  7. data/Appraisals +4 -16
  8. data/CONTRIBUTING.md +19 -8
  9. data/Gemfile +5 -9
  10. data/LICENSE +1 -1
  11. data/MIGRATING-ES.md +317 -0
  12. data/MIGRATING.md +375 -0
  13. data/NEWS +184 -31
  14. data/README.md +371 -201
  15. data/RELEASING.md +17 -0
  16. data/Rakefile +2 -2
  17. data/UPGRADING +12 -9
  18. data/features/basic_integration.feature +10 -6
  19. data/features/migration.feature +0 -24
  20. data/features/step_definitions/attachment_steps.rb +41 -35
  21. data/features/step_definitions/html_steps.rb +2 -2
  22. data/features/step_definitions/rails_steps.rb +39 -38
  23. data/features/step_definitions/s3_steps.rb +2 -2
  24. data/features/step_definitions/web_steps.rb +1 -103
  25. data/features/support/env.rb +1 -0
  26. data/features/support/file_helpers.rb +2 -2
  27. data/features/support/paths.rb +1 -1
  28. data/features/support/rails.rb +0 -24
  29. data/gemfiles/4.2.gemfile +6 -8
  30. data/gemfiles/5.0.gemfile +17 -0
  31. data/lib/generators/paperclip/paperclip_generator.rb +9 -1
  32. data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +1 -1
  33. data/lib/paperclip/attachment.rb +51 -26
  34. data/lib/paperclip/attachment_registry.rb +3 -2
  35. data/lib/paperclip/callbacks.rb +8 -6
  36. data/lib/paperclip/content_type_detector.rb +27 -11
  37. data/lib/paperclip/errors.rb +3 -1
  38. data/lib/paperclip/file_command_content_type_detector.rb +6 -8
  39. data/lib/paperclip/filename_cleaner.rb +0 -1
  40. data/lib/paperclip/geometry_detector_factory.rb +3 -3
  41. data/lib/paperclip/geometry_parser_factory.rb +1 -1
  42. data/lib/paperclip/glue.rb +1 -1
  43. data/lib/paperclip/has_attached_file.rb +9 -2
  44. data/lib/paperclip/helpers.rb +15 -11
  45. data/lib/paperclip/interpolations/plural_cache.rb +6 -5
  46. data/lib/paperclip/interpolations.rb +24 -14
  47. data/lib/paperclip/io_adapters/abstract_adapter.rb +32 -4
  48. data/lib/paperclip/io_adapters/attachment_adapter.rb +17 -6
  49. data/lib/paperclip/io_adapters/data_uri_adapter.rb +8 -8
  50. data/lib/paperclip/io_adapters/empty_string_adapter.rb +5 -4
  51. data/lib/paperclip/io_adapters/file_adapter.rb +12 -6
  52. data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +8 -7
  53. data/lib/paperclip/io_adapters/identity_adapter.rb +12 -6
  54. data/lib/paperclip/io_adapters/nil_adapter.rb +8 -5
  55. data/lib/paperclip/io_adapters/registry.rb +6 -2
  56. data/lib/paperclip/io_adapters/stringio_adapter.rb +9 -6
  57. data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +10 -6
  58. data/lib/paperclip/io_adapters/uri_adapter.rb +43 -19
  59. data/lib/paperclip/logger.rb +1 -1
  60. data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +4 -4
  61. data/lib/paperclip/media_type_spoof_detector.rb +13 -9
  62. data/lib/paperclip/processor.rb +15 -6
  63. data/lib/paperclip/rails_environment.rb +25 -0
  64. data/lib/paperclip/schema.rb +4 -10
  65. data/lib/paperclip/storage/filesystem.rb +13 -2
  66. data/lib/paperclip/storage/fog.rb +33 -20
  67. data/lib/paperclip/storage/s3.rb +89 -70
  68. data/lib/paperclip/style.rb +0 -1
  69. data/lib/paperclip/thumbnail.rb +24 -12
  70. data/lib/paperclip/url_generator.rb +17 -13
  71. data/lib/paperclip/validators/attachment_size_validator.rb +1 -7
  72. data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +4 -0
  73. data/lib/paperclip/validators.rb +1 -1
  74. data/lib/paperclip/version.rb +3 -1
  75. data/lib/paperclip.rb +27 -13
  76. data/lib/tasks/paperclip.rake +33 -3
  77. data/paperclip.gemspec +18 -15
  78. data/spec/paperclip/attachment_definitions_spec.rb +1 -1
  79. data/spec/paperclip/attachment_processing_spec.rb +2 -5
  80. data/spec/paperclip/attachment_registry_spec.rb +84 -13
  81. data/spec/paperclip/attachment_spec.rb +147 -41
  82. data/spec/paperclip/content_type_detector_spec.rb +9 -2
  83. data/spec/paperclip/file_command_content_type_detector_spec.rb +15 -2
  84. data/spec/paperclip/filename_cleaner_spec.rb +0 -1
  85. data/spec/paperclip/geometry_spec.rb +1 -1
  86. data/spec/paperclip/glue_spec.rb +44 -0
  87. data/spec/paperclip/has_attached_file_spec.rb +24 -8
  88. data/spec/paperclip/integration_spec.rb +42 -5
  89. data/spec/paperclip/interpolations_spec.rb +21 -9
  90. data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +106 -23
  91. data/spec/paperclip/io_adapters/attachment_adapter_spec.rb +6 -3
  92. data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +7 -1
  93. data/spec/paperclip/io_adapters/file_adapter_spec.rb +6 -3
  94. data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +51 -14
  95. data/spec/paperclip/io_adapters/identity_adapter_spec.rb +1 -1
  96. data/spec/paperclip/io_adapters/registry_spec.rb +2 -2
  97. data/spec/paperclip/io_adapters/stringio_adapter_spec.rb +5 -1
  98. data/spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb +5 -5
  99. data/spec/paperclip/io_adapters/uri_adapter_spec.rb +126 -8
  100. data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +10 -0
  101. data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +1 -1
  102. data/spec/paperclip/media_type_spoof_detector_spec.rb +75 -11
  103. data/spec/paperclip/paperclip_spec.rb +15 -40
  104. data/spec/paperclip/plural_cache_spec.rb +17 -16
  105. data/spec/paperclip/processor_spec.rb +4 -4
  106. data/spec/paperclip/rails_environment_spec.rb +33 -0
  107. data/spec/paperclip/schema_spec.rb +46 -46
  108. data/spec/paperclip/storage/fog_spec.rb +63 -3
  109. data/spec/paperclip/storage/s3_live_spec.rb +20 -14
  110. data/spec/paperclip/storage/s3_spec.rb +400 -215
  111. data/spec/paperclip/style_spec.rb +0 -1
  112. data/spec/paperclip/tempfile_factory_spec.rb +4 -0
  113. data/spec/paperclip/tempfile_spec.rb +35 -0
  114. data/spec/paperclip/thumbnail_spec.rb +59 -38
  115. data/spec/paperclip/url_generator_spec.rb +55 -45
  116. data/spec/paperclip/validators/attachment_size_validator_spec.rb +26 -20
  117. data/spec/paperclip/validators_spec.rb +5 -5
  118. data/spec/spec_helper.rb +7 -1
  119. data/spec/support/assertions.rb +12 -1
  120. data/spec/support/fake_model.rb +4 -0
  121. data/spec/support/fixtures/empty.xlsx +0 -0
  122. data/spec/support/matchers/have_column.rb +11 -2
  123. data/spec/support/mock_attachment.rb +2 -0
  124. data/spec/support/mock_url_generator_builder.rb +2 -2
  125. data/spec/support/model_reconstruction.rb +11 -3
  126. data/spec/support/reporting.rb +11 -0
  127. metadata +110 -63
  128. data/RUNNING_TESTS.md +0 -4
  129. data/cucumber/paperclip_steps.rb +0 -6
  130. data/gemfiles/3.2.gemfile +0 -19
  131. data/gemfiles/4.0.gemfile +0 -19
  132. data/gemfiles/4.1.gemfile +0 -19
  133. data/lib/paperclip/locales/de.yml +0 -18
  134. data/lib/paperclip/locales/es.yml +0 -18
  135. data/lib/paperclip/locales/ja.yml +0 -18
  136. data/lib/paperclip/locales/pt-BR.yml +0 -18
  137. data/lib/paperclip/locales/zh-CN.yml +0 -18
  138. data/lib/paperclip/locales/zh-HK.yml +0 -18
  139. data/lib/paperclip/locales/zh-TW.yml +0 -18
  140. data/spec/support/mock_model.rb +0 -2
  141. data/spec/support/rails_helpers.rb +0 -7
data/README.md CHANGED
@@ -1,9 +1,90 @@
1
1
  Paperclip
2
2
  =========
3
3
 
4
- [![Build Status](https://secure.travis-ci.org/thoughtbot/paperclip.png?branch=master)](http://travis-ci.org/thoughtbot/paperclip) [![Dependency Status](https://gemnasium.com/thoughtbot/paperclip.png?travis)](https://gemnasium.com/thoughtbot/paperclip) [![Code Climate](https://codeclimate.com/github/thoughtbot/paperclip.png)](https://codeclimate.com/github/thoughtbot/paperclip) [![Inline docs](http://inch-ci.org/github/thoughtbot/paperclip.png)](http://inch-ci.org/github/thoughtbot/paperclip) [![Security](https://hakiri.io/github/thoughtbot/paperclip/master.svg)](https://hakiri.io/github/thoughtbot/paperclip/master)
4
+ # Deprecated
5
5
 
6
- Paperclip is intended as an easy file attachment library for Active Record. The
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://rdoc.info/gems/paperclip) is online.
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.9.2** and Rails version **>= 3.0** (Only if you're going to use Paperclip with Ruby on Rails.)
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
- GhostScript to be installed. On Mac OS X, you can also install that using Homebrew:
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](http://en.wikipedia.org/wiki/File_(command)) is required for content type checking.
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 following:
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 - preferrably through the `PATH` variable, or by changing your `config/environments/development.rb` file
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 properties, select "Advanced System Settings"
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, this providing the ability to check the contents of a file (fixing the spoofing problem)
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", "~> 4.2"
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", :git => "git://github.com/thoughtbot/paperclip.git"
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, if you're reading it
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, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
158
- validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
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 self.up
235
+ def up
167
236
  add_attachment :users, :avatar
168
237
  end
169
238
 
170
- def self.down
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, :url => users_path, :html => { :multipart => true } do |form| %>
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
- ### Controller
187
-
188
- **Rails 3**
256
+ ### Edit and New Views with [Simple Form](https://github.com/plataformatec/simple_form)
189
257
 
190
- ```ruby
191
- def create
192
- @user = User.create( params[:user] )
193
- end
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
- **Rails 4**
265
+ ### Controller
197
266
 
198
267
  ```ruby
199
268
  def create
200
- @user = User.create( user_params )
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
- ### Show View
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 paperclip are quite simple: Declare that your model has an
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 paperclip to operate.
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, :attachment_presence => true
266
- validates_with AttachmentPresenceValidator, :attributes => :avatar
267
- validates_with AttachmentSizeValidator, :attributes => :avatar, :less_than => 1.megabytes
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, :presence => true,
287
- :content_type => { :content_type => "image/jpeg" },
288
- :size => { :in => 0..10.kilobytes }
365
+ validates_attachment :avatar, presence: true,
366
+ content_type: "image/jpeg",
367
+ size: { in: 0..10.kilobytes }
289
368
  ```
290
369
 
291
- _NOTE: Post processing will not even *start* if the attachment is not valid
292
- according to the validations. Your callbacks and processors will *only* be
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: { content_type: "application/pdf" }
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
- :content_type => { :content_type => ["image/jpeg", "image/gif", "image/png"] }
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, :content_type => /\Aimage/
455
+ validates_attachment_content_type :avatar, content_type: /\Aimage/
371
456
  # Validate filename
372
- validates_attachment_file_name :avatar, :matches => [/png\Z/, /jpe?g\Z/]
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 'text/plain'). This will prevent HTML documents from
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
- .jpg extension. This validation will only add validation errors to the form. It
388
- will not cause Errors to be raised.
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 file extensions allowed for your mime type configured by the mime-types
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 mime type "text/plain".
397
- text_plain = MIME::Types["text/plain"].first
398
- text_plain.extensions << "foo"
399
- MIME::Types.index_extensions text_plain
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 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.
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, these will get merged into Paperclip::Attachment.default_options as your Rails app boots. An example:
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 = {:storage => :fog, :fog_credentials => {:provider => "Local", :local_root => "#{Rails.root}/public"}, :fog_directory => "", :fog_host => "localhost"}
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, this method works for non-Rails applications or is an option if you prefer to place the Paperclip default settings in an initializer.
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] = {:provider => "Local", :local_root => "#{Rails.root}/public"}
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 method:
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
- ### Table Definition
524
+ The `attachment` helper can be used when creating a table:
439
525
 
440
526
  ```ruby
441
- class AddAttachmentToUsers < ActiveRecord::Migration
442
- def self.up
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
- If you're using Rails 3.2 or newer, this method works in `change` method as well:
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 AddAttachmentToUsers < ActiveRecord::Migration
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 AddAttachmentToUsers < ActiveRecord::Migration
466
- def self.up
558
+ class AddAttachmentColumnsToUsers < ActiveRecord::Migration
559
+ def up
467
560
  add_attachment :users, :avatar
468
561
  end
469
562
 
470
- def self.down
563
+ def down
471
564
  remove_attachment :users, :avatar
472
565
  end
473
566
  end
474
567
  ```
475
568
 
476
- If you're using Rails 3.2 or newer, you only need `add_attachment` in your `change` method:
569
+ Or you can do this with the `change` method:
477
570
 
478
571
  ```ruby
479
- class AddAttachmentToUsers < ActiveRecord::Migration
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 syntax
579
+ ### Vintage Syntax
487
580
 
488
- Vintage syntax (such as `t.has_attached_file` and `drop_attached_file`) are still supported in
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 is symlinked to the app's shared directory, meaning it
515
- will survive between deployments. For example, using that `:path`, you may have a
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', '~> 1.5.7'
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". However, you can do much more than just
549
- thumbnail images. By defining a subclass of Paperclip::Processor, you can
550
- perform any processing you want on the files that are attached. Any file in
551
- your Rails app's `lib/paperclip` and `lib/paperclip_processors` directories is
552
- automatically loaded by paperclip, allowing you to easily define custom
553
- processors. You can specify a processor with the :processors option to
554
- `has_attached_file`:
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 :scan, :styles => { :text => { :quality => :better } },
558
- :processors => [:ocr]
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
- This would load the hypothetical class Paperclip::Ocr, which would have the
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
- The default processor is Paperclip::Thumbnail. For backwards compatibility
566
- reasons, you can pass a single geometry string or an array containing a
567
- geometry and a format, which the file will be converted to, like so:
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 :avatar, :styles => { :thumb => ["32x32#", :png] }
716
+ has_attached_file :scan, styles: { text: { quality: :better } },
717
+ processors: [:ocr]
571
718
  ```
572
719
 
573
- This will convert the "thumb" style to a 32x32 square in png format, regardless
574
- of what was uploaded. If the format is not specified, it is kept the same (i.e.
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 :processors array. Each successive processor will
580
- be given the result of the previous processor's execution. All processors will
581
- receive the same parameters, which are what you define in the :styles hash.
582
- For example, assuming we had this definition:
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, :styles => { :text => { :quality => :better } },
586
- :processors => [:rotator, :ocr]
730
+ has_attached_file :scan, styles: { text: { quality: :better } },
731
+ processors: [:rotator, :ocr]
587
732
  ```
588
733
 
589
- then both the :rotator processor and the :ocr processor would receive the
590
- options "{ :quality => :better }". This parameter may not mean anything to one
591
- or more or the processors, and they are expected to ignore it.
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) gem.
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) gem.
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 *start* if the attachment is not valid
619
- according to the validations. Your callbacks and processors will *only* be
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
- :url => "/system/:hash.:extension",
647
- :hash_secret => "longSecretString"
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, an exception will be raised if `:hash` is used without `:hash_secret` present.
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. [https://github.com/thoughtbot/paperclip/pull/416](https://github.com/thoughtbot/paperclip/pull/416)
808
+ For more on this feature, read [the author's own explanation](https://github.com/thoughtbot/paperclip/pull/416)
658
809
 
659
- MD5 Checksum / Fingerprint
810
+ Checksum / Fingerprint
660
811
  -------
661
812
 
662
- A MD5 checksum of the original file assigned will be placed in the model if it
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 self.up
819
+ def up
669
820
  add_column :users, :avatar_fingerprint, :string
670
821
  end
671
822
 
672
- def self.down
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
- :preserve_files => "true",
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 #boss?)
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, :styles => lambda { |attachment| { :thumb => (attachment.instance.boss? ? "300x300>" : "100x100>") } }
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, :processors => lambda { |instance| instance.processors }
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 in to your environment's configuration:
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://rdoc.info/github/thoughtbot/paperclip/Paperclip.options)
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 :deploy do
940
+ namespace :paperclip do
788
941
  desc "build missing paperclip styles"
789
- task :build_missing_paperclip_styles do
942
+ task :build_missing_styles do
790
943
  on roles(:app) do
791
- execute "cd #{current_path}; RAILS_ENV=production bundle exec rake paperclip:refresh:missing_styles"
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", "deploy:build_missing_paperclip_styles")
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, :styles => {:thumb => 'x100', :croppable => '600x600>', :big => '1000x1000>'}
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, :styles => {:small => 'x100', :large => '1000x1000>'}
812
- has_attached_file :sample, :styles => {:thumb => 'x100'}
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 the
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 FactoryGirl may save multiple copies of
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
- Credits
1066
+ License
899
1067
  -------
900
1068
 
901
- ![thoughtbot](http://thoughtbot.com/logo.png)
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
- Paperclip is maintained and funded by [thoughtbot, inc](http://thoughtbot.com/community)
1072
+ About thoughtbot
1073
+ ----------------
904
1074
 
905
- Thank you to all [the contributors](https://github.com/thoughtbot/paperclip/contributors)!
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
- License
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
- Paperclip is Copyright © 2008-2014 thoughtbot, inc. It is free software, and may be
915
- redistributed under the terms specified in the MIT-LICENSE file.
1084
+ [community]: https://thoughtbot.com/community?utm_source=github
1085
+ [hire]: https://thoughtbot.com?utm_source=github