paperclip 3.5.4 → 6.1.0

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