paperclip 3.5.4 → 4.3.7

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of paperclip might be problematic. Click here for more details.

Files changed (198) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +0 -6
  3. data/.hound.yml +1066 -0
  4. data/.rubocop.yml +1 -0
  5. data/.travis.yml +11 -17
  6. data/Appraisals +6 -14
  7. data/CONTRIBUTING.md +13 -8
  8. data/Gemfile +16 -3
  9. data/LICENSE +1 -3
  10. data/NEWS +167 -49
  11. data/README.md +294 -75
  12. data/RELEASING.md +17 -0
  13. data/Rakefile +6 -8
  14. data/features/basic_integration.feature +24 -6
  15. data/features/step_definitions/attachment_steps.rb +30 -22
  16. data/features/step_definitions/html_steps.rb +2 -2
  17. data/features/step_definitions/rails_steps.rb +44 -14
  18. data/features/step_definitions/web_steps.rb +1 -103
  19. data/features/support/env.rb +2 -2
  20. data/features/support/file_helpers.rb +2 -2
  21. data/features/support/fixtures/gemfile.txt +1 -1
  22. data/features/support/rails.rb +2 -1
  23. data/gemfiles/3.2.gemfile +14 -6
  24. data/gemfiles/4.1.gemfile +19 -0
  25. data/gemfiles/4.2.gemfile +19 -0
  26. data/lib/generators/paperclip/paperclip_generator.rb +0 -2
  27. data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +1 -1
  28. data/lib/paperclip/attachment.rb +132 -38
  29. data/lib/paperclip/attachment_registry.rb +1 -1
  30. data/lib/paperclip/callbacks.rb +11 -1
  31. data/lib/paperclip/content_type_detector.rb +25 -22
  32. data/lib/paperclip/deprecations.rb +42 -0
  33. data/lib/paperclip/errors.rb +5 -0
  34. data/lib/paperclip/file_command_content_type_detector.rb +6 -8
  35. data/lib/paperclip/geometry_detector_factory.rb +3 -1
  36. data/lib/paperclip/geometry_parser_factory.rb +1 -1
  37. data/lib/paperclip/has_attached_file.rb +10 -0
  38. data/lib/paperclip/interpolations/plural_cache.rb +6 -5
  39. data/lib/paperclip/interpolations.rb +25 -12
  40. data/lib/paperclip/io_adapters/abstract_adapter.rb +3 -1
  41. data/lib/paperclip/io_adapters/attachment_adapter.rb +4 -4
  42. data/lib/paperclip/io_adapters/data_uri_adapter.rb +5 -10
  43. data/lib/paperclip/io_adapters/stringio_adapter.rb +6 -10
  44. data/lib/paperclip/io_adapters/uri_adapter.rb +30 -11
  45. data/lib/paperclip/locales/de.yml +18 -0
  46. data/lib/paperclip/locales/en.yml +1 -0
  47. data/lib/paperclip/locales/es.yml +18 -0
  48. data/lib/paperclip/locales/ja.yml +18 -0
  49. data/lib/paperclip/locales/pt-BR.yml +18 -0
  50. data/lib/paperclip/locales/zh-CN.yml +18 -0
  51. data/lib/paperclip/locales/zh-HK.yml +18 -0
  52. data/lib/paperclip/locales/zh-TW.yml +18 -0
  53. data/lib/paperclip/matchers/have_attached_file_matcher.rb +2 -1
  54. data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +2 -1
  55. data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +2 -1
  56. data/lib/paperclip/media_type_spoof_detector.rb +89 -0
  57. data/lib/paperclip/processor.rb +0 -37
  58. data/lib/paperclip/processor_helpers.rb +50 -0
  59. data/lib/paperclip/rails_environment.rb +25 -0
  60. data/lib/paperclip/schema.rb +10 -2
  61. data/lib/paperclip/storage/filesystem.rb +1 -1
  62. data/lib/paperclip/storage/fog.rb +18 -7
  63. data/lib/paperclip/storage/s3.rb +53 -22
  64. data/lib/paperclip/style.rb +8 -2
  65. data/lib/paperclip/tempfile_factory.rb +5 -1
  66. data/lib/paperclip/thumbnail.rb +12 -10
  67. data/lib/paperclip/url_generator.rb +11 -3
  68. data/lib/paperclip/validators/attachment_content_type_validator.rb +4 -0
  69. data/lib/paperclip/validators/attachment_file_name_validator.rb +80 -0
  70. data/lib/paperclip/validators/attachment_file_type_ignorance_validator.rb +29 -0
  71. data/lib/paperclip/validators/attachment_presence_validator.rb +4 -0
  72. data/lib/paperclip/validators/attachment_size_validator.rb +11 -3
  73. data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +27 -0
  74. data/lib/paperclip/validators.rb +10 -3
  75. data/lib/paperclip/version.rb +1 -1
  76. data/lib/paperclip.rb +26 -8
  77. data/lib/tasks/paperclip.rake +17 -2
  78. data/paperclip.gemspec +16 -14
  79. data/shoulda_macros/paperclip.rb +0 -1
  80. data/spec/paperclip/attachment_definitions_spec.rb +13 -0
  81. data/{test/attachment_processing_test.rb → spec/paperclip/attachment_processing_spec.rb} +20 -21
  82. data/spec/paperclip/attachment_registry_spec.rb +130 -0
  83. data/{test/attachment_test.rb → spec/paperclip/attachment_spec.rb} +438 -397
  84. data/{test/content_type_detector_test.rb → spec/paperclip/content_type_detector_spec.rb} +16 -19
  85. data/spec/paperclip/deprecations_spec.rb +65 -0
  86. data/{test/file_command_content_type_detector_test.rb → spec/paperclip/file_command_content_type_detector_spec.rb} +5 -6
  87. data/spec/paperclip/filename_cleaner_spec.rb +14 -0
  88. data/spec/paperclip/geometry_detector_spec.rb +39 -0
  89. data/{test/geometry_parser_test.rb → spec/paperclip/geometry_parser_spec.rb} +27 -27
  90. data/{test/geometry_test.rb → spec/paperclip/geometry_spec.rb} +50 -52
  91. data/spec/paperclip/glue_spec.rb +44 -0
  92. data/{test/has_attached_file_test.rb → spec/paperclip/has_attached_file_spec.rb} +45 -28
  93. data/{test/integration_test.rb → spec/paperclip/integration_spec.rb} +134 -126
  94. data/{test/interpolations_test.rb → spec/paperclip/interpolations_spec.rb} +70 -46
  95. data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +78 -0
  96. data/{test/io_adapters/attachment_adapter_test.rb → spec/paperclip/io_adapters/attachment_adapter_spec.rb} +27 -29
  97. data/{test/io_adapters/data_uri_adapter_test.rb → spec/paperclip/io_adapters/data_uri_adapter_spec.rb} +26 -17
  98. data/spec/paperclip/io_adapters/empty_string_adapter_spec.rb +17 -0
  99. data/{test/io_adapters/file_adapter_test.rb → spec/paperclip/io_adapters/file_adapter_spec.rb} +36 -40
  100. data/{test/io_adapters/http_url_proxy_adapter_test.rb → spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb} +31 -29
  101. data/spec/paperclip/io_adapters/identity_adapter_spec.rb +8 -0
  102. data/{test/io_adapters/nil_adapter_test.rb → spec/paperclip/io_adapters/nil_adapter_spec.rb} +7 -7
  103. data/{test/io_adapters/registry_test.rb → spec/paperclip/io_adapters/registry_spec.rb} +10 -7
  104. data/{test/io_adapters/stringio_adapter_test.rb → spec/paperclip/io_adapters/stringio_adapter_spec.rb} +20 -17
  105. data/{test/io_adapters/uploaded_file_adapter_test.rb → spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb} +41 -41
  106. data/{test/io_adapters/uri_adapter_test.rb → spec/paperclip/io_adapters/uri_adapter_spec.rb} +53 -28
  107. data/spec/paperclip/matchers/have_attached_file_matcher_spec.rb +19 -0
  108. data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +99 -0
  109. data/spec/paperclip/matchers/validate_attachment_presence_matcher_spec.rb +69 -0
  110. data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +88 -0
  111. data/spec/paperclip/media_type_spoof_detector_spec.rb +79 -0
  112. data/spec/paperclip/meta_class_spec.rb +30 -0
  113. data/spec/paperclip/paperclip_missing_attachment_styles_spec.rb +84 -0
  114. data/{test/paperclip_test.rb → spec/paperclip/paperclip_spec.rb} +53 -48
  115. data/spec/paperclip/plural_cache_spec.rb +37 -0
  116. data/spec/paperclip/processor_helpers_spec.rb +57 -0
  117. data/{test/processor_test.rb → spec/paperclip/processor_spec.rb} +5 -5
  118. data/spec/paperclip/rails_environment_spec.rb +33 -0
  119. data/{test/rake_test.rb → spec/paperclip/rake_spec.rb} +15 -15
  120. data/spec/paperclip/schema_spec.rb +248 -0
  121. data/{test/storage/filesystem_test.rb → spec/paperclip/storage/filesystem_spec.rb} +18 -18
  122. data/spec/paperclip/storage/fog_spec.rb +535 -0
  123. data/spec/paperclip/storage/s3_live_spec.rb +182 -0
  124. data/spec/paperclip/storage/s3_spec.rb +1526 -0
  125. data/spec/paperclip/style_spec.rb +255 -0
  126. data/spec/paperclip/tempfile_factory_spec.rb +33 -0
  127. data/{test/thumbnail_test.rb → spec/paperclip/thumbnail_spec.rb} +123 -107
  128. data/spec/paperclip/url_generator_spec.rb +211 -0
  129. data/spec/paperclip/validators/attachment_content_type_validator_spec.rb +322 -0
  130. data/spec/paperclip/validators/attachment_file_name_validator_spec.rb +160 -0
  131. data/{test/validators/attachment_presence_validator_test.rb → spec/paperclip/validators/attachment_presence_validator_spec.rb} +20 -20
  132. data/{test/validators/attachment_size_validator_test.rb → spec/paperclip/validators/attachment_size_validator_spec.rb} +65 -58
  133. data/spec/paperclip/validators/media_type_spoof_detection_validator_spec.rb +52 -0
  134. data/spec/paperclip/validators_spec.rb +164 -0
  135. data/spec/spec_helper.rb +43 -0
  136. data/spec/support/assertions.rb +71 -0
  137. data/spec/support/deprecations.rb +9 -0
  138. data/spec/support/fake_model.rb +25 -0
  139. data/spec/support/fake_rails.rb +12 -0
  140. data/spec/support/fixtures/empty.html +1 -0
  141. data/spec/support/fixtures/empty.xlsx +0 -0
  142. data/spec/support/fixtures/spaced file.jpg +0 -0
  143. data/spec/support/matchers/accept.rb +5 -0
  144. data/spec/support/matchers/exist.rb +5 -0
  145. data/spec/support/matchers/have_column.rb +23 -0
  146. data/spec/support/model_reconstruction.rb +60 -0
  147. data/spec/support/rails_helpers.rb +7 -0
  148. data/spec/support/test_data.rb +13 -0
  149. data/spec/support/version_helper.rb +9 -0
  150. metadata +334 -219
  151. data/RUNNING_TESTS.md +0 -4
  152. data/gemfiles/3.0.gemfile +0 -11
  153. data/gemfiles/3.1.gemfile +0 -11
  154. data/gemfiles/4.0.gemfile +0 -11
  155. data/test/attachment_definitions_test.rb +0 -12
  156. data/test/attachment_registry_test.rb +0 -88
  157. data/test/filename_cleaner_test.rb +0 -14
  158. data/test/generator_test.rb +0 -84
  159. data/test/geometry_detector_test.rb +0 -24
  160. data/test/helper.rb +0 -232
  161. data/test/io_adapters/abstract_adapter_test.rb +0 -58
  162. data/test/io_adapters/empty_string_adapter_test.rb +0 -18
  163. data/test/io_adapters/identity_adapter_test.rb +0 -8
  164. data/test/matchers/have_attached_file_matcher_test.rb +0 -24
  165. data/test/matchers/validate_attachment_content_type_matcher_test.rb +0 -110
  166. data/test/matchers/validate_attachment_presence_matcher_test.rb +0 -69
  167. data/test/matchers/validate_attachment_size_matcher_test.rb +0 -86
  168. data/test/meta_class_test.rb +0 -32
  169. data/test/paperclip_missing_attachment_styles_test.rb +0 -90
  170. data/test/plural_cache_test.rb +0 -36
  171. data/test/schema_test.rb +0 -200
  172. data/test/storage/fog_test.rb +0 -473
  173. data/test/storage/s3_live_test.rb +0 -179
  174. data/test/storage/s3_test.rb +0 -1356
  175. data/test/style_test.rb +0 -213
  176. data/test/support/mock_model.rb +0 -2
  177. data/test/tempfile_factory_test.rb +0 -17
  178. data/test/url_generator_test.rb +0 -187
  179. data/test/validators/attachment_content_type_validator_test.rb +0 -324
  180. data/test/validators_test.rb +0 -61
  181. /data/{test → spec}/database.yml +0 -0
  182. /data/{test → spec/support}/fixtures/12k.png +0 -0
  183. /data/{test → spec/support}/fixtures/50x50.png +0 -0
  184. /data/{test → spec/support}/fixtures/5k.png +0 -0
  185. /data/{test → spec/support}/fixtures/animated +0 -0
  186. /data/{test → spec/support}/fixtures/animated.gif +0 -0
  187. /data/{test → spec/support}/fixtures/animated.unknown +0 -0
  188. /data/{test → spec/support}/fixtures/bad.png +0 -0
  189. /data/{test → spec/support}/fixtures/fog.yml +0 -0
  190. /data/{test → spec/support}/fixtures/rotated.jpg +0 -0
  191. /data/{test → spec/support}/fixtures/s3.yml +0 -0
  192. /data/{test → spec/support}/fixtures/spaced file.png +0 -0
  193. /data/{test → spec/support}/fixtures/text.txt +0 -0
  194. /data/{test → spec/support}/fixtures/twopage.pdf +0 -0
  195. /data/{test → spec/support}/fixtures/uppercase.PNG +0 -0
  196. /data/{test → spec}/support/mock_attachment.rb +0 -0
  197. /data/{test → spec}/support/mock_interpolator.rb +0 -0
  198. /data/{test → spec}/support/mock_url_generator_builder.rb +0 -0
data/README.md CHANGED
@@ -1,7 +1,46 @@
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)
4
+ [![Build Status](https://secure.travis-ci.org/thoughtbot/paperclip.svg?branch=master)](http://travis-ci.org/thoughtbot/paperclip) [![Dependency Status](https://gemnasium.com/thoughtbot/paperclip.svg?travis)](https://gemnasium.com/thoughtbot/paperclip) [![Code Climate](https://codeclimate.com/github/thoughtbot/paperclip.svg)](https://codeclimate.com/github/thoughtbot/paperclip) [![Inline docs](http://inch-ci.org/github/thoughtbot/paperclip.svg)](http://inch-ci.org/github/thoughtbot/paperclip) [![Security](https://hakiri.io/github/thoughtbot/paperclip/master.svg)](https://hakiri.io/github/thoughtbot/paperclip/master)
5
+
6
+ - [Requirements](#requirements)
7
+ - [Ruby on Rails](#ruby-and-rails)
8
+ - [Image Processor](#image-processor)
9
+ - [file](#file)
10
+ - [Installation](#installation)
11
+ - [Quick Start](#quick-start)
12
+ - [Models](#models)
13
+ - [Migrations](#migrations)
14
+ - [Edit and New Views](#edit-and-new-views)
15
+ - [Edit and New Views with Simple Form](#edit-and-new-views-with-simple-form)
16
+ - [Controller](#controller)
17
+ - [Show View](#show-view)
18
+ - [Deleting an Attachment](#deleting-an-attachment)
19
+ - [Usage](#usage)
20
+ - [Validations](#validations)
21
+ - [Security Validations](#security-validations)
22
+ - [Defaults](#defaults)
23
+ - [Migrations](#migrations-1)
24
+ - [Table Definition](#table-definition)
25
+ - [Schema Definition](#schema-definition)
26
+ - [Vintage Syntax](#vintage-syntax)
27
+ - [Storage](#storage)
28
+ - [Understanding Storage](#understanding-storage)
29
+ - [Post Processing](#post-processing)
30
+ - [Events](#events)
31
+ - [URI Obfuscation](#uri-obfuscation)
32
+ - [MD5 Checksum / Fingerprint](#md5-checksum--fingerprint)
33
+ - [File Preservation for Soft-Delete](#file-preservation-for-soft-delete)
34
+ - [Custom Attachment Processors](#custom-attachment-processors)
35
+ - [Dynamic Configuration](#dynamic-configuration)
36
+ - [Dynamic Styles](#dynamic-styles)
37
+ - [Dynamic Processors](#dynamic-processors)
38
+ - [Logging](#logging)
39
+ - [Deployment](#deployment)
40
+ - [Testing](#testing)
41
+ - [Contributing](#contributing)
42
+ - [License](#license)
43
+ - [About thoughtbot](#about-thoughtbot)
5
44
 
6
45
  Paperclip is intended as an easy file attachment library for Active Record. The
7
46
  intent behind it was to keep setup as easy as possible and to treat files as
@@ -20,13 +59,14 @@ more detailed options.
20
59
 
21
60
  The complete [RDoc](http://rdoc.info/gems/paperclip) is online.
22
61
 
62
+ ---
23
63
 
24
64
  Requirements
25
65
  ------------
26
66
 
27
67
  ### Ruby and Rails
28
68
 
29
- 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.)
69
+ Paperclip now requires Ruby version **>= 2.0.0** and Rails version **3.2, >= 4.1** (Only if you're going to use Paperclip with Ruby on Rails.)
30
70
 
31
71
  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.
32
72
 
@@ -51,10 +91,57 @@ If you're on Mac OS X, you'll want to run the following with Homebrew:
51
91
  brew install imagemagick
52
92
 
53
93
  If you are dealing with pdf uploads or running the test suite, you'll also need
54
- GhostScript to be installed. On Mac OS X, you can also install that using Homebrew:
94
+ to install GhostScript. On Mac OS X, you can also install that using Homebrew:
55
95
 
56
96
  brew install gs
57
97
 
98
+ If you're on Ubuntu, you'll want to run the following with apt-get:
99
+
100
+ sudo apt-get install imagemagick -y
101
+
102
+ If you're on Ubuntu (or any Debian base Linux distribution), you'll want to run the following with apt-get:
103
+
104
+ sudo apt-get install imagemagick -y
105
+
106
+ ### `file`
107
+
108
+ The Unix [`file` command](http://en.wikipedia.org/wiki/File_(command)) is required for content-type checking.
109
+ This utility isn't available in Windows, but comes bundled with Ruby [Devkit](https://github.com/oneclick/rubyinstaller/wiki/Development-Kit),
110
+ so Windows users must make sure that the devkit is installed and added to the system `PATH`.
111
+
112
+ **Manual Installation**
113
+
114
+ If you're using Windows 7+ as a development environment, you may need to install the `file.exe` application manually. The `file spoofing` system in Paperclip 4+ relies on this; if you don't have it working, you'll receive `Validation failed: Upload file has an extension that does not match its contents.` errors.
115
+
116
+ To manually install, you should perform the following:
117
+
118
+ > **Download & install `file` from [this URL](http://gnuwin32.sourceforge.net/packages/file.htm)**
119
+
120
+ To test, you can use the image below:
121
+ ![untitled](https://cloud.githubusercontent.com/assets/1104431/4524452/a1f8cce4-4d44-11e4-872e-17adb96f79c9.png)
122
+
123
+ Next, you need to integrate with your environment - preferably through the `PATH` variable, or by changing your `config/environments/development.rb` file
124
+
125
+ **PATH**
126
+
127
+ 1. Click "Start"
128
+ 2. On "Computer", right-click and select "Properties"
129
+ 3. In Properties, select "Advanced System Settings"
130
+ 4. Click the "Environment Variables" button
131
+ 5. Locate the "PATH" var - at the end, add the path to your newly installed `file.exe` (typically `C:\Program Files (x86)\GnuWin32\bin`)
132
+ 6. Restart any CMD shells you have open & see if it works
133
+
134
+ OR
135
+
136
+ **Environment**
137
+
138
+ 1. Open `config/environments/development.rb`
139
+ 2. Add the following line: `Paperclip.options[:command_path] = 'C:\Program Files (x86)\GnuWin32\bin'`
140
+ 3. Restart your Rails server
141
+
142
+ 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)
143
+
144
+ ---
58
145
 
59
146
  Installation
60
147
  ------------
@@ -64,13 +151,7 @@ Paperclip is distributed as a gem, which is how it should be used in your app.
64
151
  Include the gem in your Gemfile:
65
152
 
66
153
  ```ruby
67
- gem "paperclip", "~> 3.0"
68
- ```
69
-
70
- If you're still using Rails 2.3.x, you should do this instead:
71
-
72
- ```ruby
73
- gem "paperclip", "~> 2.7"
154
+ gem "paperclip", "~> 4.3"
74
155
  ```
75
156
 
76
157
  Or, if you want to get the latest, you can get master from the main paperclip repository:
@@ -93,6 +174,8 @@ class ModuleName < ActiveRecord::Base
93
174
  end
94
175
  ```
95
176
 
177
+ ---
178
+
96
179
  Quick Start
97
180
  -----------
98
181
 
@@ -104,6 +187,7 @@ Quick Start
104
187
  class User < ActiveRecord::Base
105
188
  attr_accessible :avatar
106
189
  has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
190
+ validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
107
191
  end
108
192
  ```
109
193
 
@@ -112,6 +196,7 @@ end
112
196
  ```ruby
113
197
  class User < ActiveRecord::Base
114
198
  has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }, :default_url => "/images/:style/missing.png"
199
+ validates_attachment_content_type :avatar, :content_type => /\Aimage\/.*\Z/
115
200
  end
116
201
  ```
117
202
 
@@ -119,17 +204,17 @@ end
119
204
 
120
205
  ```ruby
121
206
  class AddAvatarColumnsToUsers < ActiveRecord::Migration
122
- def self.up
207
+ def up
123
208
  add_attachment :users, :avatar
124
209
  end
125
210
 
126
- def self.down
211
+ def down
127
212
  remove_attachment :users, :avatar
128
213
  end
129
214
  end
130
215
  ```
131
216
 
132
- (Or you can use migration generator: `rails generate paperclip user avatar`)
217
+ (Or you can use the Rails migration generator: `rails generate paperclip user avatar`)
133
218
 
134
219
  ### Edit and New Views
135
220
 
@@ -139,6 +224,13 @@ end
139
224
  <% end %>
140
225
  ```
141
226
 
227
+ ### Edit and New Views with Simple Form
228
+ ```erb
229
+ <%= simple_form_for @user, url: users_path do |form| %>
230
+ <%= form.input :avatar, as: :file %>
231
+ <% end %>
232
+ ```
233
+
142
234
  ### Controller
143
235
 
144
236
  **Rails 3**
@@ -182,14 +274,15 @@ Set the attribute to `nil` and save.
182
274
  @user.avatar = nil
183
275
  @user.save
184
276
  ```
277
+ ---
185
278
 
186
279
  Usage
187
280
  -----
188
281
 
189
- The basics of paperclip are quite simple: Declare that your model has an
282
+ The basics of Paperclip are quite simple: Declare that your model has an
190
283
  attachment with the `has_attached_file` method, and give it a name.
191
284
 
192
- Paperclip will wrap up up to four attributes (all prefixed with that attachment's name,
285
+ Paperclip will wrap up to four attributes (all prefixed with that attachment's name,
193
286
  so you can have multiple attachments per model if you wish) and give them a
194
287
  friendly front end. These attributes are:
195
288
 
@@ -198,11 +291,11 @@ friendly front end. These attributes are:
198
291
  * `<attachment>_content_type`
199
292
  * `<attachment>_updated_at`
200
293
 
201
- By default, only `<attachment>_file_name` is required for paperclip to operate.
294
+ By default, only `<attachment>_file_name` is required for Paperclip to operate.
202
295
  You'll need to add `<attachment>_content_type` in case you want to use content type
203
296
  validation.
204
297
 
205
- More information about the options to `has_attached_file` is available in the
298
+ More information about the options passed to `has_attached_file` is available in the
206
299
  documentation of [`Paperclip::ClassMethods`](http://rubydoc.info/gems/paperclip/Paperclip/ClassMethods).
207
300
 
208
301
  Validations
@@ -219,6 +312,8 @@ Example Usage:
219
312
  ```ruby
220
313
  validates :avatar, :attachment_presence => true
221
314
  validates_with AttachmentPresenceValidator, :attributes => :avatar
315
+ validates_with AttachmentSizeValidator, :attributes => :avatar, :less_than => 1.megabytes
316
+
222
317
  ```
223
318
 
224
319
  Validators can also be defined using the old helper style:
@@ -237,12 +332,12 @@ Lastly, you can also define multiple validations on a single attachment using `v
237
332
 
238
333
  ```ruby
239
334
  validates_attachment :avatar, :presence => true,
240
- :content_type => { :content_type => "image/jpg" },
335
+ :content_type => { :content_type => "image/jpeg" },
241
336
  :size => { :in => 0..10.kilobytes }
242
337
  ```
243
338
 
244
- _NOTE: Post processing will not even *start* if the attachment is not valid
245
- according to the validations. Your callbacks and processors will *only* be
339
+ _NOTE: Post-processing will not even **start** if the attachment is not valid
340
+ according to the validations. Your callbacks and processors will **only** be
246
341
  called with valid attachments._
247
342
 
248
343
  ```ruby
@@ -296,17 +391,69 @@ image-y ones:
296
391
 
297
392
  ```ruby
298
393
  validates_attachment :avatar,
299
- :content_type => { :content_type => ["image/jpg", "image/gif", "image/png"] }
394
+ :content_type => { :content_type => ["image/jpeg", "image/gif", "image/png"] }
300
395
  ```
301
396
 
302
397
  `Paperclip::ContentTypeDetector` will attempt to match a file's extension to an
303
398
  inferred content_type, regardless of the actual contents of the file.
304
399
 
400
+ ---
401
+
402
+ Security Validations
403
+ ====================
404
+
405
+ Thanks to a report from [Egor Homakov](http://homakov.blogspot.com/) we have
406
+ taken steps to prevent people from spoofing Content-Types and getting data
407
+ you weren't expecting onto your server.
408
+
409
+ NOTE: Starting at version 4.0.0, all attachments are *required* to include a
410
+ content_type validation, a file_name validation, or to explicitly state that
411
+ they're not going to have either. *Paperclip will raise an error* if you do not
412
+ do this.
413
+
414
+ ```ruby
415
+ class ActiveRecord::Base
416
+ has_attached_file :avatar
417
+ # Validate content type
418
+ validates_attachment_content_type :avatar, :content_type => /\Aimage/
419
+ # Validate filename
420
+ validates_attachment_file_name :avatar, :matches => [/png\Z/, /jpe?g\Z/]
421
+ # Explicitly do not validate
422
+ do_not_validate_attachment_file_type :avatar
423
+ end
424
+ ```
425
+
426
+ This keeps Paperclip secure-by-default, and will prevent people trying to mess
427
+ with your filesystem.
428
+
429
+ NOTE: Also starting at version 4.0.0, Paperclip has another validation that
430
+ cannot be turned off. This validation will prevent content type spoofing. That
431
+ is, uploading a PHP document (for example) as part of the EXIF tags of a
432
+ well-formed JPEG. This check is limited to the media type (the first part of the
433
+ MIME type, so, 'text' in `text/plain`). This will prevent HTML documents from
434
+ being uploaded as JPEGs, but will not prevent GIFs from being uploaded with a
435
+ `.jpg` extension. This validation will only add validation errors to the form. It
436
+ will not cause errors to be raised.
437
+
438
+ This can sometimes cause false validation errors in applications that use custom
439
+ file extensions. In these cases you may wish to add your custom extension to the
440
+ list of file extensions allowed for your MIME type configured by the `mime-types`
441
+ gem:
442
+
443
+ ```ruby
444
+ # Allow ".foo" as an extension for files with the MIME type "text/plain".
445
+ text_plain = MIME::Types["text/plain"].first
446
+ text_plain.extensions << "foo"
447
+ MIME::Types.index_extensions text_plain
448
+ ```
449
+
450
+ ---
451
+
305
452
  Defaults
306
453
  --------
307
- 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.
454
+ 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.
308
455
 
309
- 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:
456
+ 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:
310
457
 
311
458
  ```ruby
312
459
  module YourApp
@@ -318,7 +465,7 @@ module YourApp
318
465
  end
319
466
  ```
320
467
 
321
- 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.
468
+ 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.
322
469
 
323
470
  An example Rails initializer would look something like this:
324
471
 
@@ -328,29 +475,36 @@ Paperclip::Attachment.default_options[:fog_credentials] = {:provider => "Local",
328
475
  Paperclip::Attachment.default_options[:fog_directory] = ""
329
476
  Paperclip::Attachment.default_options[:fog_host] = "http://localhost:3000"
330
477
  ```
478
+ ---
331
479
 
332
480
  Migrations
333
481
  ----------
334
482
 
335
- Paperclip defines several migration methods which can be used to create necessary columns in your
336
- model. There are two types of method:
483
+ Paperclip defines several migration methods which can be used to create the necessary columns in your
484
+ model. There are two types of helper methods to aid in this, as follows:
485
+
486
+ ### Add Attachment Column To A Table
337
487
 
338
- ### Table Definition
488
+ The `attachment` helper can be used when creating a table:
339
489
 
340
490
  ```ruby
341
- class AddAttachmentToUsers < ActiveRecord::Migration
342
- def self.up
491
+ class CreateUsersWithAttachments < ActiveRecord::Migration
492
+ def up
343
493
  create_table :users do |t|
344
494
  t.attachment :avatar
345
495
  end
496
+
497
+ # This is assuming you are only using the users table for Paperclip attachment. Drop with care!
498
+ def down
499
+ drop_table :users
346
500
  end
347
501
  end
348
502
  ```
349
503
 
350
- If you're using Rails 3.2 or newer, this method works in `change` method as well:
504
+ You can also use the `change` method, instead of the `up`/`down` combination above, as shown below:
351
505
 
352
506
  ```ruby
353
- class AddAttachmentToUsers < ActiveRecord::Migration
507
+ class CreateUsersWithAttachments < ActiveRecord::Migration
354
508
  def change
355
509
  create_table :users do |t|
356
510
  t.attachment :avatar
@@ -361,22 +515,24 @@ end
361
515
 
362
516
  ### Schema Definition
363
517
 
518
+ Alternatively, the `add_attachment` and `remove_attachment` methods can be used to add new Paperclip columns to an existing table:
519
+
364
520
  ```ruby
365
- class AddAttachmentToUsers < ActiveRecord::Migration
366
- def self.up
521
+ class AddAttachmentColumnsToUsers < ActiveRecord::Migration
522
+ def up
367
523
  add_attachment :users, :avatar
368
524
  end
369
525
 
370
- def self.down
526
+ def down
371
527
  remove_attachment :users, :avatar
372
528
  end
373
529
  end
374
530
  ```
375
531
 
376
- If you're using Rails 3.2 or newer, you only need `add_attachment` in your `change` method:
532
+ Or you can do this with the `change` method:
377
533
 
378
534
  ```ruby
379
- class AddAttachmentToUsers < ActiveRecord::Migration
535
+ class AddAttachmentColumnsToUsers < ActiveRecord::Migration
380
536
  def change
381
537
  add_attachment :users, :avatar
382
538
  end
@@ -385,9 +541,11 @@ end
385
541
 
386
542
  ### Vintage syntax
387
543
 
388
- Vintage syntax (such as `t.has_attached_file` and `drop_attached_file`) are still supported in
544
+ Vintage syntax (such as `t.has_attached_file` and `drop_attached_file`) is still supported in
389
545
  Paperclip 3.x, but you're advised to update those migration files to use this new syntax.
390
546
 
547
+ ---
548
+
391
549
  Storage
392
550
  -------
393
551
 
@@ -422,7 +580,7 @@ You may also choose to store your files using Amazon's S3 service. To do so, inc
422
580
  the `aws-sdk` gem in your Gemfile:
423
581
 
424
582
  ```ruby
425
- gem 'aws-sdk', '~> 1.5.7'
583
+ gem 'aws-sdk', '~> 1.6'
426
584
  ```
427
585
 
428
586
  And then you can specify using S3 from `has_attached_file`.
@@ -436,17 +594,20 @@ both the `:path` and `:url` options in order to make sure the files are unavaila
436
594
  to the public. Both `:path` and `:url` allow the same set of interpolated
437
595
  variables.
438
596
 
597
+ ---
598
+
439
599
  Post Processing
440
600
  ---------------
441
601
 
442
602
  Paperclip supports an extensible selection of post-processors. When you define
443
603
  a set of styles for an attachment, by default it is expected that those
444
- "styles" are actually "thumbnails". However, you can do much more than just
604
+ "styles" are actually "thumbnails." However, you can do much more than just
445
605
  thumbnail images. By defining a subclass of Paperclip::Processor, you can
446
606
  perform any processing you want on the files that are attached. Any file in
447
- your Rails app's lib/paperclip\_processors directory is automatically loaded by
448
- paperclip, allowing you to easily define custom processors. You can specify a
449
- processor with the :processors option to `has_attached_file`:
607
+ your Rails app's `lib/paperclip` and `lib/paperclip_processors` directories is
608
+ automatically loaded by Paperclip, allowing you to easily define custom
609
+ processors. You can specify a processor with the `:processors` option to
610
+ `has_attached_file`:
450
611
 
451
612
  ```ruby
452
613
  has_attached_file :scan, :styles => { :text => { :quality => :better } },
@@ -459,21 +620,21 @@ more information about defining processors, see Paperclip::Processor.
459
620
 
460
621
  The default processor is Paperclip::Thumbnail. For backwards compatibility
461
622
  reasons, you can pass a single geometry string or an array containing a
462
- geometry and a format, which the file will be converted to, like so:
623
+ geometry and a format that the file will be converted to, like so:
463
624
 
464
625
  ```ruby
465
626
  has_attached_file :avatar, :styles => { :thumb => ["32x32#", :png] }
466
627
  ```
467
628
 
468
- This will convert the "thumb" style to a 32x32 square in png format, regardless
629
+ This will convert the "thumb" style to a 32x32 square in PNG format, regardless
469
630
  of what was uploaded. If the format is not specified, it is kept the same (i.e.
470
- jpgs will remain jpgs). For more information on the accepted style formats, see
631
+ JPGs will remain JPGs). For more information on the accepted style formats, see
471
632
  [here](http://www.imagemagick.org/script/command-line-processing.php#geometry).
472
633
 
473
634
  Multiple processors can be specified, and they will be invoked in the order
474
- they are defined in the :processors array. Each successive processor will
635
+ they are defined in the `:processors` array. Each successive processor will
475
636
  be given the result of the previous processor's execution. All processors will
476
- receive the same parameters, which are what you define in the :styles hash.
637
+ receive the same parameters, which are defined in the `:styles` hash.
477
638
  For example, assuming we had this definition:
478
639
 
479
640
  ```ruby
@@ -482,18 +643,20 @@ has_attached_file :scan, :styles => { :text => { :quality => :better } },
482
643
  ```
483
644
 
484
645
  then both the :rotator processor and the :ocr processor would receive the
485
- options "{ :quality => :better }". This parameter may not mean anything to one
646
+ options `{ :quality => :better }`. This parameter may not mean anything to one
486
647
  or more or the processors, and they are expected to ignore it.
487
648
 
488
649
  _NOTE: Because processors operate by turning the original attachment into the
489
650
  styles, no processors will be run if there are no styles defined._
490
651
 
491
652
  If you're interested in caching your thumbnail's width, height and size in the
492
- database, take a look at the [paperclip-meta](https://github.com/y8/paperclip-meta) gem.
653
+ database, take a look at the [paperclip-meta](https://github.com/teeparham/paperclip-meta) gem.
493
654
 
494
655
  Also, if you're interested in generating the thumbnail on-the-fly, you might want
495
656
  to look into the [attachment_on_the_fly](https://github.com/drpentode/Attachment-on-the-Fly) gem.
496
657
 
658
+ ---
659
+
497
660
  Events
498
661
  ------
499
662
 
@@ -508,8 +671,8 @@ normal ActiveRecord callbacks as possible, so if you return false (specifically
508
671
  will halt. Returning false in an `after_filter` will not halt anything, but you
509
672
  can access the model and the attachment if necessary.
510
673
 
511
- _NOTE: Post processing will not even *start* if the attachment is not valid
512
- according to the validations. Your callbacks and processors will *only* be
674
+ _NOTE: Post processing will not even **start** if the attachment is not valid
675
+ according to the validations. Your callbacks and processors will **only** be
513
676
  called with valid attachments._
514
677
 
515
678
  ```ruby
@@ -524,6 +687,8 @@ class Message < ActiveRecord::Base
524
687
  end
525
688
  ```
526
689
 
690
+ ---
691
+
527
692
  URI Obfuscation
528
693
  ---------------
529
694
 
@@ -543,29 +708,44 @@ has_attached_file :avatar, {
543
708
  The `:hash` interpolation will be replaced with a unique hash made up of whatever
544
709
  is specified in `:hash_data`. The default value for `:hash_data` is `":class/:attachment/:id/:style/:updated_at"`.
545
710
 
546
- `:hash_secret` is required, an exception will be raised if `:hash` is used without `:hash_secret` present.
711
+ `:hash_secret` is required - an exception will be raised if `:hash` is used without `:hash_secret` present.
547
712
 
548
- 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)
713
+ For more on this feature, read [the author's own explanation](https://github.com/thoughtbot/paperclip/pull/416)
549
714
 
550
715
  MD5 Checksum / Fingerprint
551
716
  -------
552
717
 
553
- A MD5 checksum of the original file assigned will be placed in the model if it
718
+ An MD5 checksum of the original file assigned will be placed in the model if it
554
719
  has an attribute named fingerprint. Following the user model migration example
555
- above, the migration would look like the following.
720
+ above, the migration would look like the following:
556
721
 
557
722
  ```ruby
558
723
  class AddAvatarFingerprintColumnToUser < ActiveRecord::Migration
559
- def self.up
724
+ def up
560
725
  add_column :users, :avatar_fingerprint, :string
561
726
  end
562
727
 
563
- def self.down
728
+ def down
564
729
  remove_column :users, :avatar_fingerprint
565
730
  end
566
731
  end
567
732
  ```
568
733
 
734
+ File Preservation for Soft-Delete
735
+ -------
736
+
737
+ An option is available to preserve attachments in order to play nicely with soft-deleted models. (acts_as_paranoid, paranoia, etc.)
738
+
739
+ ```ruby
740
+ has_attached_file :some_attachment, {
741
+ :preserve_files => "true",
742
+ }
743
+ ```
744
+
745
+ This will prevent ```some_attachment``` from being wiped out when the model gets destroyed, so it will still exist when the object is restored later.
746
+
747
+ ---
748
+
569
749
  Custom Attachment Processors
570
750
  -------
571
751
 
@@ -574,15 +754,16 @@ to inherit from `Paperclip::Processor` (see `lib/paperclip/processor.rb`).
574
754
  For example, when `:styles` are specified for an image attachment, the
575
755
  thumbnail processor (see `lib/paperclip/thumbnail.rb`) is loaded without having
576
756
  to specify it as a `:processor` parameter to `has_attached_file`. When any
577
- other processor is defined it must be called out in the `:processors`
757
+ other processor is defined, it must be called out in the `:processors`
578
758
  parameter if it is to be applied to the attachment. The thumbnail processor
579
- uses the imagemagick `convert` command to do the work of resizing image
759
+ uses the ImageMagick `convert` command to do the work of resizing image
580
760
  thumbnails. It would be easy to create a custom processor that watermarks
581
- an image using imagemagick's `composite` command. Following the
761
+ an image using ImageMagick's `composite` command. Following the
582
762
  implementation pattern of the thumbnail processor would be a way to implement a
583
763
  watermark processor. All kinds of attachment processors can be created;
584
764
  a few utility examples would be compression and encryption processors.
585
765
 
766
+ ---
586
767
 
587
768
  Dynamic Configuration
588
769
  ---------------------
@@ -597,7 +778,7 @@ instances.
597
778
  ### Dynamic Styles:
598
779
 
599
780
  Imagine a user model that had different styles based on the role of the user.
600
- Perhaps some users are bosses (e.g. a User model instance responds to #boss?)
781
+ Perhaps some users are bosses (e.g. a User model instance responds to `#boss?`)
601
782
  and merit a bigger avatar thumbnail than regular users. The configuration to
602
783
  determine what style parameters are to be used based on the user role might
603
784
  look as follows where a boss will receive a `300x300` thumbnail otherwise a
@@ -623,10 +804,12 @@ processors, where a defined `watermark` processor is invoked after the
623
804
  ```ruby
624
805
  class User < ActiveRecord::Base
625
806
  has_attached_file :avatar, :processors => lambda { |instance| instance.processors }
626
- attr_accessor :watermark
807
+ attr_accessor :processors
627
808
  end
628
809
  ```
629
810
 
811
+ ---
812
+
630
813
  Logging
631
814
  ----------
632
815
 
@@ -641,6 +824,8 @@ end
641
824
 
642
825
  More information in the [rdocs](http://rdoc.info/github/thoughtbot/paperclip/Paperclip.options)
643
826
 
827
+ ---
828
+
644
829
  Deployment
645
830
  ----------
646
831
 
@@ -657,16 +842,22 @@ Here is an example for Capistrano:
657
842
  ```ruby
658
843
  namespace :deploy do
659
844
  desc "build missing paperclip styles"
660
- task :build_missing_paperclip_styles, :roles => :app do
661
- run "cd #{release_path}; RAILS_ENV=production bundle exec rake paperclip:refresh:missing_styles"
845
+ task :build_missing_paperclip_styles do
846
+ on roles(:app) do
847
+ within release_path do
848
+ with rails_env: fetch(:rails_env) do
849
+ execute :rake, "paperclip:refresh:missing_styles"
850
+ end
851
+ end
852
+ end
662
853
  end
663
854
  end
664
855
 
665
- after("deploy:update_code", "deploy:build_missing_paperclip_styles")
856
+ after("deploy:compile_assets", "deploy:build_missing_paperclip_styles")
666
857
  ```
667
858
 
668
859
  Now you don't have to remember to refresh thumbnails in production every time you add a new style.
669
- Unfortunately it does not work with dynamic styles - it just ignores them.
860
+ Unfortunately, it does not work with dynamic styles - it just ignores them.
670
861
 
671
862
  If you already have a working app and don't want `rake paperclip:refresh:missing_styles` to refresh old pictures, you need to tell
672
863
  Paperclip about existing styles. Simply create a `paperclip_attachments.yml` file by hand. For example:
@@ -699,6 +890,8 @@ Then in `RAILS_ROOT/public/system/paperclip_attachments.yml`:
699
890
  - :thumb
700
891
  ```
701
892
 
893
+ ---
894
+
702
895
  Testing
703
896
  -------
704
897
 
@@ -722,9 +915,29 @@ else
722
915
  end
723
916
  ```
724
917
 
725
- The important part here being the inclusion of `ENV['TEST_ENV_NUMBER']`, or the
918
+ The important part here being the inclusion of `ENV['TEST_ENV_NUMBER']`, or a
726
919
  similar mechanism for whichever parallel testing library you use.
727
920
 
921
+ **Integration Tests**
922
+
923
+ Using integration tests with FactoryGirl may save multiple copies of
924
+ your test files within the app. To avoid this, specify a custom path in
925
+ the `config/environments/test.rb` like so:
926
+
927
+ ```ruby
928
+ Paperclip::Attachment.default_options[:path] = "#{Rails.root}/spec/test_files/:class/:id_partition/:style.:extension"
929
+ ```
930
+
931
+ Then, make sure to delete that directory after the test suite runs by adding
932
+ this to `spec_helper.rb`.
933
+
934
+ ```ruby
935
+ config.after(:suite) do
936
+ FileUtils.rm_rf(Dir["#{Rails.root}/spec/test_files/"])
937
+ end
938
+ ```
939
+ ---
940
+
728
941
  Contributing
729
942
  ------------
730
943
 
@@ -740,19 +953,25 @@ guidelines:
740
953
 
741
954
  Please see `CONTRIBUTING.md` for more details on contributing and running test.
742
955
 
743
- Credits
956
+ Thank you to all [the contributors](https://github.com/thoughtbot/paperclip/contributors)!
957
+
958
+ License
744
959
  -------
745
960
 
746
- ![thoughtbot](http://thoughtbot.com/logo.png)
961
+ Paperclip is Copyright © 2008-2015 thoughtbot, inc. It is free software, and may be
962
+ redistributed under the terms specified in the MIT-LICENSE file.
747
963
 
748
- Paperclip is maintained and funded by [thoughtbot, inc](http://thoughtbot.com/community)
964
+ About thoughtbot
965
+ ----------------
749
966
 
750
- Thank you to all [the contributors](https://github.com/thoughtbot/paperclip/contributors)!
967
+ ![thoughtbot](https://thoughtbot.com/logo.png)
751
968
 
969
+ Paperclip is maintained and funded by thoughtbot.
752
970
  The names and logos for thoughtbot are trademarks of thoughtbot, inc.
753
971
 
754
- License
755
- -------
972
+ We love open source software!
973
+ See [our other projects][community] or
974
+ [hire us][hire] to design, develop, and grow your product.
756
975
 
757
- Paperclip is Copyright © 2008-2013 thoughtbot, inc. It is free software, and may be
758
- redistributed under the terms specified in the MIT-LICENSE file.
976
+ [community]: https://thoughtbot.com/community?utm_source=github
977
+ [hire]: https://thoughtbot.com?utm_source=github