paperclip 4.2.4 → 5.2.0

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