paperclip 3.5.4 → 6.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.codeclimate.yml +17 -0
- data/.github/issue_template.md +3 -0
- data/.gitignore +0 -6
- data/.hound.yml +1055 -0
- data/.rubocop.yml +1 -0
- data/.travis.yml +17 -20
- data/Appraisals +4 -16
- data/CONTRIBUTING.md +29 -13
- data/Gemfile +11 -3
- data/LICENSE +1 -3
- data/MIGRATING-ES.md +317 -0
- data/MIGRATING.md +375 -0
- data/NEWS +262 -49
- data/README.md +496 -169
- data/RELEASING.md +17 -0
- data/Rakefile +6 -8
- data/UPGRADING +12 -9
- data/features/basic_integration.feature +27 -8
- data/features/migration.feature +0 -24
- data/features/step_definitions/attachment_steps.rb +44 -36
- data/features/step_definitions/html_steps.rb +2 -2
- data/features/step_definitions/rails_steps.rb +68 -37
- data/features/step_definitions/s3_steps.rb +2 -2
- data/features/step_definitions/web_steps.rb +1 -103
- data/features/support/env.rb +3 -2
- data/features/support/file_helpers.rb +2 -2
- data/features/support/fixtures/gemfile.txt +1 -1
- data/features/support/paths.rb +1 -1
- data/features/support/rails.rb +2 -25
- data/gemfiles/4.2.gemfile +17 -0
- data/gemfiles/5.0.gemfile +17 -0
- data/lib/generators/paperclip/paperclip_generator.rb +9 -3
- data/lib/generators/paperclip/templates/paperclip_migration.rb.erb +2 -2
- data/lib/paperclip/attachment.rb +170 -52
- data/lib/paperclip/attachment_registry.rb +3 -2
- data/lib/paperclip/callbacks.rb +13 -1
- data/lib/paperclip/content_type_detector.rb +26 -22
- data/lib/paperclip/errors.rb +8 -1
- data/lib/paperclip/file_command_content_type_detector.rb +6 -8
- data/lib/paperclip/filename_cleaner.rb +0 -1
- data/lib/paperclip/geometry_detector_factory.rb +6 -4
- data/lib/paperclip/geometry_parser_factory.rb +1 -1
- data/lib/paperclip/glue.rb +1 -1
- data/lib/paperclip/has_attached_file.rb +17 -1
- data/lib/paperclip/helpers.rb +15 -11
- data/lib/paperclip/interpolations/plural_cache.rb +6 -5
- data/lib/paperclip/interpolations.rb +31 -13
- data/lib/paperclip/io_adapters/abstract_adapter.rb +34 -5
- data/lib/paperclip/io_adapters/attachment_adapter.rb +19 -8
- data/lib/paperclip/io_adapters/data_uri_adapter.rb +11 -16
- data/lib/paperclip/io_adapters/empty_string_adapter.rb +5 -4
- data/lib/paperclip/io_adapters/file_adapter.rb +12 -6
- data/lib/paperclip/io_adapters/http_url_proxy_adapter.rb +8 -7
- data/lib/paperclip/io_adapters/identity_adapter.rb +12 -6
- data/lib/paperclip/io_adapters/nil_adapter.rb +8 -5
- data/lib/paperclip/io_adapters/registry.rb +6 -2
- data/lib/paperclip/io_adapters/stringio_adapter.rb +15 -16
- data/lib/paperclip/io_adapters/uploaded_file_adapter.rb +10 -6
- data/lib/paperclip/io_adapters/uri_adapter.rb +43 -19
- data/lib/paperclip/locales/en.yml +1 -0
- data/lib/paperclip/logger.rb +1 -1
- data/lib/paperclip/matchers/have_attached_file_matcher.rb +2 -1
- data/lib/paperclip/matchers/validate_attachment_content_type_matcher.rb +4 -4
- data/lib/paperclip/matchers/validate_attachment_presence_matcher.rb +2 -1
- data/lib/paperclip/matchers/validate_attachment_size_matcher.rb +2 -1
- data/lib/paperclip/media_type_spoof_detector.rb +93 -0
- data/lib/paperclip/processor.rb +15 -43
- data/lib/paperclip/processor_helpers.rb +50 -0
- data/lib/paperclip/rails_environment.rb +25 -0
- data/lib/paperclip/schema.rb +10 -8
- data/lib/paperclip/storage/filesystem.rb +14 -3
- data/lib/paperclip/storage/fog.rb +38 -20
- data/lib/paperclip/storage/s3.rb +124 -73
- data/lib/paperclip/style.rb +8 -3
- data/lib/paperclip/tempfile_factory.rb +5 -1
- data/lib/paperclip/thumbnail.rb +34 -19
- data/lib/paperclip/url_generator.rb +26 -14
- data/lib/paperclip/validators/attachment_content_type_validator.rb +4 -0
- data/lib/paperclip/validators/attachment_file_name_validator.rb +80 -0
- data/lib/paperclip/validators/attachment_file_type_ignorance_validator.rb +29 -0
- data/lib/paperclip/validators/attachment_presence_validator.rb +4 -0
- data/lib/paperclip/validators/attachment_size_validator.rb +5 -3
- data/lib/paperclip/validators/media_type_spoof_detection_validator.rb +31 -0
- data/lib/paperclip/validators.rb +11 -4
- data/lib/paperclip/version.rb +3 -1
- data/lib/paperclip.rb +31 -11
- data/lib/tasks/paperclip.rake +34 -5
- data/paperclip.gemspec +21 -16
- data/shoulda_macros/paperclip.rb +0 -1
- data/spec/paperclip/attachment_definitions_spec.rb +13 -0
- data/{test/attachment_processing_test.rb → spec/paperclip/attachment_processing_spec.rb} +17 -21
- data/spec/paperclip/attachment_registry_spec.rb +158 -0
- data/{test/attachment_test.rb → spec/paperclip/attachment_spec.rb} +519 -409
- data/{test/content_type_detector_test.rb → spec/paperclip/content_type_detector_spec.rb} +17 -20
- data/spec/paperclip/file_command_content_type_detector_spec.rb +40 -0
- data/spec/paperclip/filename_cleaner_spec.rb +13 -0
- data/spec/paperclip/geometry_detector_spec.rb +39 -0
- data/{test/geometry_parser_test.rb → spec/paperclip/geometry_parser_spec.rb} +27 -27
- data/{test/geometry_test.rb → spec/paperclip/geometry_spec.rb} +50 -52
- data/spec/paperclip/glue_spec.rb +44 -0
- data/spec/paperclip/has_attached_file_spec.rb +158 -0
- data/{test/integration_test.rb → spec/paperclip/integration_spec.rb} +174 -129
- data/{test/interpolations_test.rb → spec/paperclip/interpolations_spec.rb} +79 -46
- data/spec/paperclip/io_adapters/abstract_adapter_spec.rb +160 -0
- data/{test/io_adapters/attachment_adapter_test.rb → spec/paperclip/io_adapters/attachment_adapter_spec.rb} +33 -32
- data/spec/paperclip/io_adapters/data_uri_adapter_spec.rb +89 -0
- data/spec/paperclip/io_adapters/empty_string_adapter_spec.rb +17 -0
- data/{test/io_adapters/file_adapter_test.rb → spec/paperclip/io_adapters/file_adapter_spec.rb} +38 -42
- data/spec/paperclip/io_adapters/http_url_proxy_adapter_spec.rb +138 -0
- data/spec/paperclip/io_adapters/identity_adapter_spec.rb +8 -0
- data/{test/io_adapters/nil_adapter_test.rb → spec/paperclip/io_adapters/nil_adapter_spec.rb} +7 -7
- data/{test/io_adapters/registry_test.rb → spec/paperclip/io_adapters/registry_spec.rb} +12 -9
- data/{test/io_adapters/stringio_adapter_test.rb → spec/paperclip/io_adapters/stringio_adapter_spec.rb} +21 -18
- data/{test/io_adapters/uploaded_file_adapter_test.rb → spec/paperclip/io_adapters/uploaded_file_adapter_spec.rb} +46 -46
- data/spec/paperclip/io_adapters/uri_adapter_spec.rb +220 -0
- data/spec/paperclip/matchers/have_attached_file_matcher_spec.rb +19 -0
- data/spec/paperclip/matchers/validate_attachment_content_type_matcher_spec.rb +109 -0
- data/spec/paperclip/matchers/validate_attachment_presence_matcher_spec.rb +69 -0
- data/spec/paperclip/matchers/validate_attachment_size_matcher_spec.rb +88 -0
- data/spec/paperclip/media_type_spoof_detector_spec.rb +120 -0
- data/spec/paperclip/meta_class_spec.rb +30 -0
- data/spec/paperclip/paperclip_missing_attachment_styles_spec.rb +84 -0
- data/spec/paperclip/paperclip_spec.rb +192 -0
- data/spec/paperclip/plural_cache_spec.rb +37 -0
- data/spec/paperclip/processor_helpers_spec.rb +57 -0
- data/{test/processor_test.rb → spec/paperclip/processor_spec.rb} +7 -7
- data/spec/paperclip/rails_environment_spec.rb +33 -0
- data/{test/rake_test.rb → spec/paperclip/rake_spec.rb} +15 -15
- data/spec/paperclip/schema_spec.rb +248 -0
- data/{test/storage/filesystem_test.rb → spec/paperclip/storage/filesystem_spec.rb} +18 -18
- data/spec/paperclip/storage/fog_spec.rb +566 -0
- data/spec/paperclip/storage/s3_live_spec.rb +188 -0
- data/spec/paperclip/storage/s3_spec.rb +1693 -0
- data/spec/paperclip/style_spec.rb +254 -0
- data/spec/paperclip/tempfile_factory_spec.rb +33 -0
- data/spec/paperclip/tempfile_spec.rb +35 -0
- data/{test/thumbnail_test.rb → spec/paperclip/thumbnail_spec.rb} +158 -137
- data/spec/paperclip/url_generator_spec.rb +221 -0
- data/spec/paperclip/validators/attachment_content_type_validator_spec.rb +322 -0
- data/spec/paperclip/validators/attachment_file_name_validator_spec.rb +160 -0
- data/{test/validators/attachment_presence_validator_test.rb → spec/paperclip/validators/attachment_presence_validator_spec.rb} +20 -20
- data/{test/validators/attachment_size_validator_test.rb → spec/paperclip/validators/attachment_size_validator_spec.rb} +77 -64
- data/spec/paperclip/validators/media_type_spoof_detection_validator_spec.rb +52 -0
- data/spec/paperclip/validators_spec.rb +164 -0
- data/spec/spec_helper.rb +46 -0
- data/spec/support/assertions.rb +82 -0
- data/spec/support/fake_model.rb +25 -0
- data/spec/support/fake_rails.rb +12 -0
- data/spec/support/fixtures/empty.html +1 -0
- data/spec/support/fixtures/empty.xlsx +0 -0
- data/spec/support/fixtures/spaced file.jpg +0 -0
- data/spec/support/matchers/accept.rb +5 -0
- data/spec/support/matchers/exist.rb +5 -0
- data/spec/support/matchers/have_column.rb +23 -0
- data/{test → spec}/support/mock_attachment.rb +2 -0
- data/{test → spec}/support/mock_url_generator_builder.rb +2 -2
- data/spec/support/model_reconstruction.rb +68 -0
- data/spec/support/reporting.rb +11 -0
- data/spec/support/test_data.rb +13 -0
- data/spec/support/version_helper.rb +9 -0
- metadata +344 -226
- data/RUNNING_TESTS.md +0 -4
- data/cucumber/paperclip_steps.rb +0 -6
- data/gemfiles/3.0.gemfile +0 -11
- data/gemfiles/3.1.gemfile +0 -11
- data/gemfiles/3.2.gemfile +0 -11
- data/gemfiles/4.0.gemfile +0 -11
- data/test/attachment_definitions_test.rb +0 -12
- data/test/attachment_registry_test.rb +0 -88
- data/test/file_command_content_type_detector_test.rb +0 -27
- data/test/filename_cleaner_test.rb +0 -14
- data/test/generator_test.rb +0 -84
- data/test/geometry_detector_test.rb +0 -24
- data/test/has_attached_file_test.rb +0 -125
- data/test/helper.rb +0 -232
- data/test/io_adapters/abstract_adapter_test.rb +0 -58
- data/test/io_adapters/data_uri_adapter_test.rb +0 -74
- data/test/io_adapters/empty_string_adapter_test.rb +0 -18
- data/test/io_adapters/http_url_proxy_adapter_test.rb +0 -102
- data/test/io_adapters/identity_adapter_test.rb +0 -8
- data/test/io_adapters/uri_adapter_test.rb +0 -102
- data/test/matchers/have_attached_file_matcher_test.rb +0 -24
- data/test/matchers/validate_attachment_content_type_matcher_test.rb +0 -110
- data/test/matchers/validate_attachment_presence_matcher_test.rb +0 -69
- data/test/matchers/validate_attachment_size_matcher_test.rb +0 -86
- data/test/meta_class_test.rb +0 -32
- data/test/paperclip_missing_attachment_styles_test.rb +0 -90
- data/test/paperclip_test.rb +0 -217
- data/test/plural_cache_test.rb +0 -36
- data/test/schema_test.rb +0 -200
- data/test/storage/fog_test.rb +0 -473
- data/test/storage/s3_live_test.rb +0 -179
- data/test/storage/s3_test.rb +0 -1356
- data/test/style_test.rb +0 -213
- data/test/support/mock_model.rb +0 -2
- data/test/tempfile_factory_test.rb +0 -17
- data/test/url_generator_test.rb +0 -187
- data/test/validators/attachment_content_type_validator_test.rb +0 -324
- data/test/validators_test.rb +0 -61
- /data/{test → spec}/database.yml +0 -0
- /data/{test → spec/support}/fixtures/12k.png +0 -0
- /data/{test → spec/support}/fixtures/50x50.png +0 -0
- /data/{test → spec/support}/fixtures/5k.png +0 -0
- /data/{test → spec/support}/fixtures/animated +0 -0
- /data/{test → spec/support}/fixtures/animated.gif +0 -0
- /data/{test → spec/support}/fixtures/animated.unknown +0 -0
- /data/{test → spec/support}/fixtures/bad.png +0 -0
- /data/{test → spec/support}/fixtures/fog.yml +0 -0
- /data/{test → spec/support}/fixtures/rotated.jpg +0 -0
- /data/{test → spec/support}/fixtures/s3.yml +0 -0
- /data/{test → spec/support}/fixtures/spaced file.png +0 -0
- /data/{test → spec/support}/fixtures/text.txt +0 -0
- /data/{test → spec/support}/fixtures/twopage.pdf +0 -0
- /data/{test → spec/support}/fixtures/uppercase.PNG +0 -0
- /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
|
-
|
4
|
+
# Deprecated
|
5
5
|
|
6
|
-
Paperclip is
|
6
|
+
**[Paperclip is deprecated]**.
|
7
|
+
|
8
|
+
For new projects, we recommend Rails' own [ActiveStorage].
|
9
|
+
|
10
|
+
For existing projects, please consult and contribute to [the migration guide] ([en español]).
|
11
|
+
|
12
|
+
|
13
|
+
We will leave the Issues open as a discussion forum _only_. We do _not_
|
14
|
+
guarantee a response from us in the Issues.
|
15
|
+
|
16
|
+
We are no longer accepting pull requests _except_ pull requests against the
|
17
|
+
migration guide. All other pull requests will be closed without merging.
|
18
|
+
|
19
|
+
[Paperclip is deprecated]: https://robots.thoughtbot.com/closing-the-trombone
|
20
|
+
[ActiveStorage]: http://guides.rubyonrails.org/active_storage_overview.html
|
21
|
+
[the migration guide]: https://github.com/thoughtbot/paperclip/blob/master/MIGRATING.md
|
22
|
+
[en español]: https://github.com/thoughtbot/paperclip/blob/master/MIGRATING-ES.md
|
23
|
+
|
24
|
+
# Existing documentation
|
25
|
+
|
26
|
+
## Documentation valid for `master` branch
|
27
|
+
|
28
|
+
Please check the documentation for the paperclip version you are using:
|
29
|
+
https://github.com/thoughtbot/paperclip/releases
|
30
|
+
|
31
|
+
---
|
32
|
+
|
33
|
+
[![Build Status](https://secure.travis-ci.org/thoughtbot/paperclip.svg?branch=master)](http://travis-ci.org/thoughtbot/paperclip)
|
34
|
+
[![Dependency Status](https://gemnasium.com/thoughtbot/paperclip.svg?travis)](https://gemnasium.com/thoughtbot/paperclip)
|
35
|
+
[![Code Climate](https://codeclimate.com/github/thoughtbot/paperclip.svg)](https://codeclimate.com/github/thoughtbot/paperclip)
|
36
|
+
[![Inline docs](http://inch-ci.org/github/thoughtbot/paperclip.svg)](http://inch-ci.org/github/thoughtbot/paperclip)
|
37
|
+
[![Security](https://hakiri.io/github/thoughtbot/paperclip/master.svg)](https://hakiri.io/github/thoughtbot/paperclip/master)
|
38
|
+
|
39
|
+
<!-- START doctoc generated TOC please keep comment here to allow auto update -->
|
40
|
+
<!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE -->
|
41
|
+
|
42
|
+
- [Requirements](#requirements)
|
43
|
+
- [Ruby and Rails](#ruby-and-rails)
|
44
|
+
- [Image Processor](#image-processor)
|
45
|
+
- [`file`](#file)
|
46
|
+
- [Installation](#installation)
|
47
|
+
- [Quick Start](#quick-start)
|
48
|
+
- [Models](#models)
|
49
|
+
- [Migrations](#migrations)
|
50
|
+
- [Edit and New Views](#edit-and-new-views)
|
51
|
+
- [Edit and New Views with Simple Form](#edit-and-new-views-with-simple-form)
|
52
|
+
- [Controller](#controller)
|
53
|
+
- [View Helpers](#view-helpers)
|
54
|
+
- [Checking a File Exists](#checking-a-file-exists)
|
55
|
+
- [Deleting an Attachment](#deleting-an-attachment)
|
56
|
+
- [Usage](#usage)
|
57
|
+
- [Validations](#validations)
|
58
|
+
- [Internationalization (I18n)](#internationalization-i18n)
|
59
|
+
- [Security Validations](#security-validations)
|
60
|
+
- [Defaults](#defaults)
|
61
|
+
- [Migrations](#migrations-1)
|
62
|
+
- [Add Attachment Column To A Table](#add-attachment-column-to-a-table)
|
63
|
+
- [Schema Definition](#schema-definition)
|
64
|
+
- [Vintage Syntax](#vintage-syntax)
|
65
|
+
- [Storage](#storage)
|
66
|
+
- [Understanding Storage](#understanding-storage)
|
67
|
+
- [IO Adapters](#io-adapters)
|
68
|
+
- [Post Processing](#post-processing)
|
69
|
+
- [Custom Attachment Processors](#custom-attachment-processors)
|
70
|
+
- [Events](#events)
|
71
|
+
- [URI Obfuscation](#uri-obfuscation)
|
72
|
+
- [Checksum / Fingerprint](#checksum--fingerprint)
|
73
|
+
- [File Preservation for Soft-Delete](#file-preservation-for-soft-delete)
|
74
|
+
- [Dynamic Configuration](#dynamic-configuration)
|
75
|
+
- [Dynamic Styles:](#dynamic-styles)
|
76
|
+
- [Dynamic Processors:](#dynamic-processors)
|
77
|
+
- [Logging](#logging)
|
78
|
+
- [Deployment](#deployment)
|
79
|
+
- [Attachment Styles](#attachment-styles)
|
80
|
+
- [Testing](#testing)
|
81
|
+
- [Contributing](#contributing)
|
82
|
+
- [License](#license)
|
83
|
+
- [About thoughtbot](#about-thoughtbot)
|
84
|
+
|
85
|
+
<!-- END doctoc generated TOC please keep comment here to allow auto update -->
|
86
|
+
|
87
|
+
Paperclip is intended as an easy file attachment library for ActiveRecord. The
|
7
88
|
intent behind it was to keep setup as easy as possible and to treat files as
|
8
89
|
much like other attributes as possible. This means they aren't saved to their
|
9
90
|
final locations on disk, nor are they deleted if set to nil, until
|
@@ -15,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://
|
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
|
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
|
-
|
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", "~>
|
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", :
|
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
|
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, :
|
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
|
235
|
+
def up
|
123
236
|
add_attachment :users, :avatar
|
124
237
|
end
|
125
238
|
|
126
|
-
def
|
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, :
|
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
|
-
###
|
143
|
-
|
144
|
-
**Rails 3**
|
256
|
+
### Edit and New Views with [Simple Form](https://github.com/plataformatec/simple_form)
|
145
257
|
|
146
|
-
```
|
147
|
-
|
148
|
-
|
149
|
-
|
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
|
-
|
265
|
+
### Controller
|
153
266
|
|
154
267
|
```ruby
|
155
268
|
def create
|
156
|
-
@user = User.create(
|
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
|
-
###
|
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
|
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
|
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
|
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, :
|
221
|
-
validates_with AttachmentPresenceValidator, :
|
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, :
|
240
|
-
|
241
|
-
:
|
365
|
+
validates_attachment :avatar, presence: true,
|
366
|
+
content_type: "image/jpeg",
|
367
|
+
size: { in: 0..10.kilobytes }
|
242
368
|
```
|
243
369
|
|
244
|
-
_NOTE: Post
|
245
|
-
according to the validations. Your callbacks and processors will
|
370
|
+
_NOTE: Post-processing will not even **start** if the attachment is not valid
|
371
|
+
according to the validations. Your callbacks and processors will **only** be
|
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:
|
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
|
-
|
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
|
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
|
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 = {:
|
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
|
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] = {:
|
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
|
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
|
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
|
342
|
-
def
|
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
|
-
|
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
|
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
|
366
|
-
def
|
558
|
+
class AddAttachmentColumnsToUsers < ActiveRecord::Migration
|
559
|
+
def up
|
367
560
|
add_attachment :users, :avatar
|
368
561
|
end
|
369
562
|
|
370
|
-
def
|
563
|
+
def down
|
371
564
|
remove_attachment :users, :avatar
|
372
565
|
end
|
373
566
|
end
|
374
567
|
```
|
375
568
|
|
376
|
-
|
569
|
+
Or you can do this with the `change` method:
|
377
570
|
|
378
571
|
```ruby
|
379
|
-
class
|
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
|
579
|
+
### Vintage Syntax
|
387
580
|
|
388
|
-
Vintage syntax (such as `t.has_attached_file` and `drop_attached_file`)
|
581
|
+
Vintage syntax (such as `t.has_attached_file` and `drop_attached_file`) is still supported in
|
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
|
413
|
-
|
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'
|
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"
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
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 :
|
453
|
-
|
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
|
-
|
457
|
-
|
458
|
-
|
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
|
-
|
461
|
-
|
462
|
-
|
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 :
|
716
|
+
has_attached_file :scan, styles: { text: { quality: :better } },
|
717
|
+
processors: [:ocr]
|
466
718
|
```
|
467
719
|
|
468
|
-
This
|
469
|
-
|
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
|
475
|
-
|
476
|
-
|
477
|
-
|
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, :
|
481
|
-
:
|
730
|
+
has_attached_file :scan, styles: { text: { quality: :better } },
|
731
|
+
processors: [:rotator, :ocr]
|
482
732
|
```
|
483
733
|
|
484
|
-
|
485
|
-
options
|
486
|
-
|
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/
|
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)
|
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
|
512
|
-
according to the validations. Your callbacks and processors will
|
769
|
+
_NOTE: Post processing will not even **start** if the attachment is not valid
|
770
|
+
according to the validations. Your callbacks and processors will **only** be
|
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
|
-
:
|
538
|
-
:
|
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
|
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
|
808
|
+
For more on this feature, read [the author's own explanation](https://github.com/thoughtbot/paperclip/pull/416)
|
549
809
|
|
550
|
-
|
810
|
+
Checksum / Fingerprint
|
551
811
|
-------
|
552
812
|
|
553
|
-
A
|
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
|
819
|
+
def up
|
560
820
|
add_column :users, :avatar_fingerprint, :string
|
561
821
|
end
|
562
822
|
|
563
|
-
def
|
823
|
+
def down
|
564
824
|
remove_column :users, :avatar_fingerprint
|
565
825
|
end
|
566
826
|
end
|
567
827
|
```
|
568
828
|
|
569
|
-
|
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
|
-
|
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
|
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, :
|
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, :
|
626
|
-
attr_accessor :
|
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
|
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://
|
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 :
|
940
|
+
namespace :paperclip do
|
659
941
|
desc "build missing paperclip styles"
|
660
|
-
task :
|
661
|
-
|
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:
|
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, :
|
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, :
|
681
|
-
has_attached_file :sample, :
|
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
|
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
|
-
|
1066
|
+
License
|
744
1067
|
-------
|
745
1068
|
|
746
|
-
|
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
|
-
|
1072
|
+
About thoughtbot
|
1073
|
+
----------------
|
749
1074
|
|
750
|
-
|
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
|
-
|
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
|
-
|
758
|
-
|
1084
|
+
[community]: https://thoughtbot.com/community?utm_source=github
|
1085
|
+
[hire]: https://thoughtbot.com?utm_source=github
|